| 
									
										
										
										
											2023-02-08 18:12:00 +01:00
										 |  |  | /* Simple Plugin API */ | 
					
						
							|  |  |  | /* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans <wim.taymans@gmail.com> */ | 
					
						
							|  |  |  | /* SPDX-License-Identifier: MIT */ | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-20 21:04:33 +01:00
										 |  |  | #include <locale.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | #include "pwtest.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | #include <spa/utils/defs.h>
 | 
					
						
							|  |  |  | #include <spa/utils/json.h>
 | 
					
						
							| 
									
										
										
										
											2021-05-18 11:36:13 +10:00
										 |  |  | #include <spa/utils/string.h>
 | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | PWTEST(json_abi) | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-12-04 09:36:05 +01:00
										 |  |  | #if defined(__x86_64__) && defined(__LP64__)
 | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | 	pwtest_int_eq(sizeof(struct spa_json), 32U); | 
					
						
							|  |  |  | 	return PWTEST_PASS; | 
					
						
							| 
									
										
										
										
											2020-12-04 09:36:05 +01:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 	fprintf(stderr, "%zd\n", sizeof(struct spa_json)); | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | 	return PWTEST_SKIP; | 
					
						
							| 
									
										
										
										
											2020-12-04 09:36:05 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define TYPE_OBJECT	0
 | 
					
						
							|  |  |  | #define TYPE_ARRAY	1
 | 
					
						
							|  |  |  | #define TYPE_STRING	2
 | 
					
						
							|  |  |  | #define TYPE_BOOL	3
 | 
					
						
							|  |  |  | #define TYPE_NULL	4
 | 
					
						
							|  |  |  | #define TYPE_TRUE	5
 | 
					
						
							|  |  |  | #define TYPE_FALSE	6
 | 
					
						
							|  |  |  | #define TYPE_FLOAT	7
 | 
					
						
							| 
									
										
										
										
											2024-03-23 20:44:51 +02:00
										 |  |  | #define TYPE_INT	8
 | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | static void check_type(int type, const char *value, int len) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | 	pwtest_bool_eq(spa_json_is_object(value, len), (type == TYPE_OBJECT)); | 
					
						
							|  |  |  | 	pwtest_bool_eq(spa_json_is_array(value, len), (type == TYPE_ARRAY)); | 
					
						
							|  |  |  | 	pwtest_bool_eq(spa_json_is_string(value, len), (type == TYPE_STRING)); | 
					
						
							|  |  |  | 	pwtest_bool_eq(spa_json_is_bool(value, len), | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | 			(type == TYPE_BOOL || type == TYPE_TRUE || type == TYPE_FALSE)); | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | 	pwtest_bool_eq(spa_json_is_null(value, len), (type == TYPE_NULL)); | 
					
						
							| 
									
										
										
										
											2024-03-23 20:44:51 +02:00
										 |  |  | 	if (type == TYPE_BOOL) { | 
					
						
							|  |  |  | 		pwtest_bool_true(spa_json_is_true(value, len) || spa_json_is_false(value, len)); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		pwtest_bool_eq(spa_json_is_true(value, len), type == TYPE_TRUE); | 
					
						
							|  |  |  | 		pwtest_bool_eq(spa_json_is_false(value, len), type == TYPE_FALSE); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (type) { | 
					
						
							|  |  |  | 	case TYPE_FLOAT: | 
					
						
							|  |  |  | 		pwtest_bool_true(spa_json_is_float(value, len)); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case TYPE_INT: | 
					
						
							|  |  |  | 		pwtest_bool_true(spa_json_is_int(value, len)); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		pwtest_bool_false(spa_json_is_float(value, len)); | 
					
						
							|  |  |  | 		pwtest_bool_false(spa_json_is_int(value, len)); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void expect_type(struct spa_json *it, int type) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const char *value; | 
					
						
							|  |  |  | 	int len; | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | 	pwtest_int_gt((len = spa_json_next(it, &value)), 0); | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | 	check_type(type, value, len); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-23 20:44:51 +02:00
										 |  |  | static void expect_end(struct spa_json *it) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const char *value; | 
					
						
							|  |  |  | 	struct spa_json it2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	pwtest_int_eq(spa_json_next(it, &value), 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* end is idempotent */ | 
					
						
							|  |  |  | 	memcpy(&it2, it, sizeof(*it)); | 
					
						
							|  |  |  | 	pwtest_int_eq(spa_json_next(it, &value), 0); | 
					
						
							|  |  |  | 	pwtest_int_eq(memcmp(&it2, it, sizeof(*it)), 0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-20 19:42:02 +02:00
										 |  |  | static void expect_parse_error(struct spa_json *it, const char *str, int line, int col) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const char *value; | 
					
						
							|  |  |  | 	struct spa_json it2; | 
					
						
							|  |  |  | 	int linepos, colpos; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	pwtest_int_eq(spa_json_next(it, &value), -1); | 
					
						
							|  |  |  | 	pwtest_bool_true(spa_json_get_error(it, str, &linepos, &colpos)); | 
					
						
							|  |  |  | 	pwtest_int_eq(linepos, line); | 
					
						
							|  |  |  | 	pwtest_int_eq(colpos, col); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* parse error is idempotent also for parents */ | 
					
						
							|  |  |  | 	while (it) { | 
					
						
							|  |  |  | 		memcpy(&it2, it, sizeof(*it)); | 
					
						
							|  |  |  | 		pwtest_int_eq(spa_json_next(it, &value), -1); | 
					
						
							|  |  |  | 		pwtest_int_eq(memcmp(&it2, it, sizeof(*it)), 0); | 
					
						
							|  |  |  | 		it = it->parent; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-23 20:44:51 +02:00
										 |  |  | static void expect_array(struct spa_json *it, struct spa_json *sub) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	pwtest_int_eq(spa_json_enter_array(it, sub), 1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void expect_object(struct spa_json *it, struct spa_json *sub) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	pwtest_int_eq(spa_json_enter_object(it, sub), 1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | static void expect_string(struct spa_json *it, const char *str) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const char *value; | 
					
						
							|  |  |  | 	int len; | 
					
						
							|  |  |  | 	char *s; | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | 	pwtest_int_gt((len = spa_json_next(it, &value)), 0); | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | 	check_type(TYPE_STRING, value, len); | 
					
						
							| 
									
										
										
										
											2021-01-19 16:56:55 +01:00
										 |  |  | 	s = alloca(len+1); | 
					
						
							| 
									
										
										
										
											2024-03-20 19:42:02 +02:00
										 |  |  | 	pwtest_int_eq(spa_json_parse_stringn(value, len, s, len+1), 1); | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | 	pwtest_str_eq(s, str); | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2024-03-23 20:44:51 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | static void expect_string_or_bare(struct spa_json *it, const char *str) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const char *value; | 
					
						
							|  |  |  | 	int len; | 
					
						
							|  |  |  | 	char *s; | 
					
						
							|  |  |  | 	pwtest_int_gt((len = spa_json_next(it, &value)), 0); | 
					
						
							|  |  |  | 	s = alloca(len+1); | 
					
						
							|  |  |  | 	pwtest_int_eq(spa_json_parse_stringn(value, len, s, len+1), 1); | 
					
						
							|  |  |  | 	pwtest_str_eq(s, str); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | static void expect_float(struct spa_json *it, float val) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const char *value; | 
					
						
							|  |  |  | 	int len; | 
					
						
							| 
									
										
										
										
											2022-07-11 11:50:58 +02:00
										 |  |  | 	float f = 0.0f; | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | 	pwtest_int_gt((len = spa_json_next(it, &value)), 0); | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | 	check_type(TYPE_FLOAT, value, len); | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | 	pwtest_int_gt(spa_json_parse_float(value, len, &f), 0); | 
					
						
							|  |  |  | 	pwtest_double_eq(f, val); | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-23 20:44:51 +02:00
										 |  |  | static void expect_int(struct spa_json *it, int val) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const char *value; | 
					
						
							|  |  |  | 	int len; | 
					
						
							|  |  |  | 	int f = 0; | 
					
						
							|  |  |  | 	pwtest_int_gt((len = spa_json_next(it, &value)), 0); | 
					
						
							|  |  |  | 	check_type(TYPE_INT, value, len); | 
					
						
							|  |  |  | 	pwtest_int_gt(spa_json_parse_int(value, len, &f), 0); | 
					
						
							|  |  |  | 	pwtest_int_eq(f, val); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void expect_bool(struct spa_json *it, bool val) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const char *value; | 
					
						
							|  |  |  | 	int len; | 
					
						
							|  |  |  | 	bool f = false; | 
					
						
							|  |  |  | 	pwtest_int_gt((len = spa_json_next(it, &value)), 0); | 
					
						
							|  |  |  | 	check_type(TYPE_BOOL, value, len); | 
					
						
							|  |  |  | 	check_type(val ? TYPE_TRUE : TYPE_FALSE, value, len); | 
					
						
							|  |  |  | 	pwtest_int_gt(spa_json_parse_bool(value, len, &f), 0); | 
					
						
							|  |  |  | 	pwtest_int_eq(f, val); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void expect_null(struct spa_json *it) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const char *value; | 
					
						
							|  |  |  | 	int len; | 
					
						
							|  |  |  | 	pwtest_int_gt((len = spa_json_next(it, &value)), 0); | 
					
						
							|  |  |  | 	check_type(TYPE_NULL, value, len); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | PWTEST(json_parse) | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-20 19:42:02 +02:00
										 |  |  | 	char buf[1024]; | 
					
						
							|  |  |  | 	int i; | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | 	struct spa_json it[5]; | 
					
						
							|  |  |  | 	const char *json = " { " | 
					
						
							| 
									
										
										
										
											2024-03-20 19:42:02 +02:00
										 |  |  | 			"\"foo\": \"bar\", # comment\n" | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | 			"\"foo\\\"  \":   true,       " | 
					
						
							|  |  |  | 			"\"foo \\n\\r\\t\": false," | 
					
						
							|  |  |  | 			"  \"  arr\": [ true, false, null, 5, 5.7, \"str]\"]," | 
					
						
							|  |  |  | 			"\"foo 2\":     null," | 
					
						
							|  |  |  | 			"\"foo 3\": 1," | 
					
						
							|  |  |  | 			"  \"obj\": { \"ba } z\": false, \"empty\": [], \"foo\": { }, \"1.9\", 1.9 }," | 
					
						
							|  |  |  | 			"\"foo 4\"   : 1.8,   " | 
					
						
							|  |  |  | 			"\"foo 5\": -1.8  , " | 
					
						
							|  |  |  | 			"\"foo 6\":   +2.8   ," | 
					
						
							|  |  |  | 			" } ", *value; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	expect_type(&it[0], TYPE_OBJECT); | 
					
						
							|  |  |  | 	spa_json_enter(&it[0], &it[1]); | 
					
						
							|  |  |  | 	expect_string(&it[1], "foo"); | 
					
						
							|  |  |  | 	expect_string(&it[1], "bar"); | 
					
						
							|  |  |  | 	expect_string(&it[1], "foo\"  "); | 
					
						
							|  |  |  | 	expect_type(&it[1], TYPE_TRUE); | 
					
						
							|  |  |  | 	expect_string(&it[1], "foo \n\r\t"); | 
					
						
							|  |  |  | 	expect_type(&it[1], TYPE_FALSE); | 
					
						
							|  |  |  | 	expect_string(&it[1], "  arr"); | 
					
						
							|  |  |  | 	expect_type(&it[1], TYPE_ARRAY); | 
					
						
							|  |  |  | 	spa_json_enter(&it[1], &it[2]); | 
					
						
							|  |  |  | 	expect_string(&it[1], "foo 2"); | 
					
						
							|  |  |  | 	expect_type(&it[1], TYPE_NULL); | 
					
						
							|  |  |  | 	expect_string(&it[1], "foo 3"); | 
					
						
							|  |  |  | 	expect_float(&it[1], 1.f); | 
					
						
							|  |  |  | 	expect_string(&it[1], "obj"); | 
					
						
							|  |  |  | 	expect_type(&it[1], TYPE_OBJECT); | 
					
						
							|  |  |  | 	spa_json_enter(&it[1], &it[3]); | 
					
						
							|  |  |  | 	expect_string(&it[1], "foo 4"); | 
					
						
							|  |  |  | 	expect_float(&it[1], 1.8f); | 
					
						
							|  |  |  | 	expect_string(&it[1], "foo 5"); | 
					
						
							|  |  |  | 	expect_float(&it[1], -1.8f); | 
					
						
							|  |  |  | 	expect_string(&it[1], "foo 6"); | 
					
						
							|  |  |  | 	expect_float(&it[1], +2.8f); | 
					
						
							| 
									
										
										
										
											2024-03-20 19:42:02 +02:00
										 |  |  | 	expect_end(&it[1]); | 
					
						
							|  |  |  | 	expect_end(&it[0]); | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | 	/* in the array */ | 
					
						
							|  |  |  | 	expect_type(&it[2], TYPE_TRUE); | 
					
						
							|  |  |  | 	expect_type(&it[2], TYPE_FALSE); | 
					
						
							|  |  |  | 	expect_type(&it[2], TYPE_NULL); | 
					
						
							|  |  |  | 	expect_float(&it[2], 5.f); | 
					
						
							|  |  |  | 	expect_float(&it[2], 5.7f); | 
					
						
							|  |  |  | 	expect_string(&it[2], "str]"); | 
					
						
							|  |  |  | 	/* in the object */ | 
					
						
							|  |  |  | 	expect_string(&it[3], "ba } z"); | 
					
						
							|  |  |  | 	expect_type(&it[3], TYPE_FALSE); | 
					
						
							|  |  |  | 	expect_string(&it[3], "empty"); | 
					
						
							|  |  |  | 	expect_type(&it[3], TYPE_ARRAY); | 
					
						
							|  |  |  | 	spa_json_enter(&it[3], &it[4]); | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | 	pwtest_int_eq(spa_json_next(&it[4], &value), 0); | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | 	expect_string(&it[3], "foo"); | 
					
						
							|  |  |  | 	expect_type(&it[3], TYPE_OBJECT); | 
					
						
							|  |  |  | 	spa_json_enter(&it[3], &it[4]); | 
					
						
							|  |  |  | 	expect_string(&it[3], "1.9"); | 
					
						
							|  |  |  | 	expect_float(&it[3], 1.9f); | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-20 19:42:02 +02:00
										 |  |  | 	expect_end(&it[3]); | 
					
						
							|  |  |  | 	expect_end(&it[2]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	pwtest_bool_false(spa_json_get_error(&it[0], NULL, NULL, NULL)); | 
					
						
							|  |  |  | 	pwtest_bool_false(spa_json_get_error(&it[1], NULL, NULL, NULL)); | 
					
						
							|  |  |  | 	pwtest_bool_false(spa_json_get_error(&it[2], NULL, NULL, NULL)); | 
					
						
							|  |  |  | 	pwtest_bool_false(spa_json_get_error(&it[3], NULL, NULL, NULL)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	json = "section={\"key\":value}, section2=[item1,item2]"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	expect_string_or_bare(&it[0], "section"); | 
					
						
							|  |  |  | 	expect_object(&it[0], &it[1]); | 
					
						
							|  |  |  | 	expect_string_or_bare(&it[0], "section2"); | 
					
						
							|  |  |  | 	expect_array(&it[0], &it[1]); | 
					
						
							|  |  |  | 	expect_end(&it[0]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	expect_string_or_bare(&it[0], "section"); | 
					
						
							|  |  |  | 	expect_object(&it[0], &it[1]); | 
					
						
							|  |  |  | 	expect_string(&it[1], "key"); | 
					
						
							|  |  |  | 	expect_string_or_bare(&it[1], "value"); | 
					
						
							|  |  |  | 	expect_string_or_bare(&it[0], "section2"); | 
					
						
							|  |  |  | 	expect_array(&it[0], &it[1]); | 
					
						
							|  |  |  | 	expect_string_or_bare(&it[1], "item1"); | 
					
						
							|  |  |  | 	expect_string_or_bare(&it[1], "item2"); | 
					
						
							|  |  |  | 	expect_end(&it[0]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* 2-byte utf8 */ | 
					
						
							|  |  |  | 	json = "\"\xc3\xa4\", \"\xc3\xa4\""; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	expect_string(&it[0], "\xc3\xa4"); | 
					
						
							|  |  |  | 	expect_string(&it[0], "\xc3\xa4"); | 
					
						
							|  |  |  | 	expect_end(&it[0]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* 3-byte utf8 */ | 
					
						
							|  |  |  | 	json = "\"\xe6\xad\xa3\", \"\xe6\xad\xa3\""; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	expect_string(&it[0], "\xe6\xad\xa3"); | 
					
						
							|  |  |  | 	expect_string(&it[0], "\xe6\xad\xa3"); | 
					
						
							|  |  |  | 	expect_end(&it[0]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* 4-byte utf8 */ | 
					
						
							|  |  |  | 	json = "\"\xf0\x92\x80\x80\", \"\xf0\x92\x80\x80\""; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	expect_string(&it[0], "\xf0\x92\x80\x80"); | 
					
						
							|  |  |  | 	expect_string(&it[0], "\xf0\x92\x80\x80"); | 
					
						
							|  |  |  | 	expect_end(&it[0]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* run-in comment in bare */ | 
					
						
							|  |  |  | 	json = "foo#comment"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	expect_string_or_bare(&it[0], "foo"); | 
					
						
							|  |  |  | 	expect_end(&it[0]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* end of parsing idempotent */ | 
					
						
							|  |  |  | 	json = "{}"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	expect_object(&it[0], &it[1]); | 
					
						
							|  |  |  | 	expect_end(&it[0]); | 
					
						
							|  |  |  | 	expect_end(&it[0]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* overflowing parser nesting stack is not an error */ | 
					
						
							|  |  |  | 	for (i = 0; i < 256; ++i) | 
					
						
							|  |  |  | 		buf[i] = '['; | 
					
						
							|  |  |  | 	for (; i < 512; ++i) | 
					
						
							|  |  |  | 		buf[i] = ']'; | 
					
						
							|  |  |  | 	buf[i++] = '\0'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spa_json_init(&it[0], buf, strlen(buf)); | 
					
						
							|  |  |  | 	pwtest_int_eq(spa_json_next(&it[0], &value), 1); | 
					
						
							|  |  |  | 	expect_end(&it[0]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-23 20:44:51 +02:00
										 |  |  | 	/* non-null terminated strings OK */ | 
					
						
							|  |  |  | 	json = "1.234"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, 4); | 
					
						
							|  |  |  | 	expect_float(&it[0], 1.23); | 
					
						
							|  |  |  | 	expect_end(&it[0]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	json = "1234"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, 3); | 
					
						
							|  |  |  | 	expect_int(&it[0], 123); | 
					
						
							|  |  |  | 	expect_end(&it[0]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	json = "truey"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, 4); | 
					
						
							|  |  |  | 	expect_bool(&it[0], true); | 
					
						
							|  |  |  | 	expect_end(&it[0]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	json = "falsey"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, 5); | 
					
						
							|  |  |  | 	expect_bool(&it[0], false); | 
					
						
							|  |  |  | 	expect_end(&it[0]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	json = "nully"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, 4); | 
					
						
							|  |  |  | 	expect_null(&it[0]); | 
					
						
							|  |  |  | 	expect_end(&it[0]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	json = "{}y{]"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, 2); | 
					
						
							|  |  |  | 	expect_object(&it[0], &it[1]); | 
					
						
							|  |  |  | 	expect_end(&it[0]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	json = "[]y{]"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, 2); | 
					
						
							|  |  |  | 	expect_array(&it[0], &it[1]); | 
					
						
							|  |  |  | 	expect_end(&it[0]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	json = "helloy"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, 5); | 
					
						
							|  |  |  | 	expect_string_or_bare(&it[0], "hello"); | 
					
						
							|  |  |  | 	expect_end(&it[0]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	json = "\"hello\"y"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, 7); | 
					
						
							|  |  |  | 	expect_string(&it[0], "hello"); | 
					
						
							|  |  |  | 	expect_end(&it[0]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | 	return PWTEST_PASS; | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-20 19:42:02 +02:00
										 |  |  | PWTEST(json_parse_fail) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char buf[1024]; | 
					
						
							|  |  |  | 	struct spa_json it[5]; | 
					
						
							|  |  |  | 	const char *json, *value; | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* = in array */ | 
					
						
							|  |  |  | 	json = "[ foo = bar ]"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	expect_array(&it[0], &it[1]); | 
					
						
							|  |  |  | 	expect_string_or_bare(&it[1], "foo"); | 
					
						
							|  |  |  | 	expect_parse_error(&it[1], json, 1, 7); | 
					
						
							|  |  |  | 	expect_parse_error(&it[1], json, 1, 7);  /* parse error is idempotent */ | 
					
						
							|  |  |  | 	expect_parse_error(&it[0], json, 1, 7);  /* parse error visible in parent */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* : in array */ | 
					
						
							|  |  |  | 	json = "[ foo, bar\n : quux ]"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	expect_array(&it[0], &it[1]); | 
					
						
							|  |  |  | 	expect_string_or_bare(&it[1], "foo"); | 
					
						
							|  |  |  | 	expect_string_or_bare(&it[1], "bar"); | 
					
						
							|  |  |  | 	expect_parse_error(&it[1], json, 2, 2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* missing ] */ | 
					
						
							|  |  |  | 	json = "[ foo, bar"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	pwtest_int_eq(spa_json_next(&it[0], &value), 1); | 
					
						
							|  |  |  | 	expect_parse_error(&it[0], json, 1, 11); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* spurious ] */ | 
					
						
							|  |  |  | 	json = "foo, bar ]"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	pwtest_int_eq(spa_json_next(&it[0], &value), 3); | 
					
						
							|  |  |  | 	pwtest_int_eq(spa_json_next(&it[0], &value), 3); | 
					
						
							|  |  |  | 	expect_parse_error(&it[0], json, 1, 10); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* spurious } */ | 
					
						
							|  |  |  | 	json = "{ foo, bar } }"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	expect_object(&it[0], &it[1]); | 
					
						
							|  |  |  | 	expect_parse_error(&it[0], json, 1, 14); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* bad nesting */ | 
					
						
							|  |  |  | 	json = "{ {[{[{[{[{[{[{[{[{[{[{[{[ ]}]}]}]}]}]}]}]}]}]}]}]} ]"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	pwtest_int_eq(spa_json_next(&it[0], &value), 1); | 
					
						
							|  |  |  | 	expect_parse_error(&it[0], json, 1, strlen(json)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* bad nesting */ | 
					
						
							|  |  |  | 	json = "[ {[{[{[{[{[{[{[{[{[{[{[{[ ]}]}]}]}]}]}]}]}]}]}]}]} }"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	pwtest_int_eq(spa_json_next(&it[0], &value), 1); | 
					
						
							|  |  |  | 	expect_parse_error(&it[0], json, 1, strlen(json)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* unclosed string */ | 
					
						
							|  |  |  | 	json = "\"foo"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	expect_parse_error(&it[0], json, 1, 5); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* unclosed string */ | 
					
						
							|  |  |  | 	json = "foo\""; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	expect_string_or_bare(&it[0], "foo"); | 
					
						
							|  |  |  | 	expect_parse_error(&it[0], json, 1, 5); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* unclosed string */ | 
					
						
							|  |  |  | 	json = "foo\"bar"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	expect_string_or_bare(&it[0], "foo"); | 
					
						
							|  |  |  | 	expect_parse_error(&it[0], json, 1, 8); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* unclosed escape */ | 
					
						
							|  |  |  | 	json = "\"\\"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	expect_parse_error(&it[0], json, 1, 3); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* bare escape */ | 
					
						
							|  |  |  | 	json = "foo\\n"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	expect_parse_error(&it[0], json, 1, 4); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* bare escape */ | 
					
						
							|  |  |  | 	json = "\\nfoo"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	expect_parse_error(&it[0], json, 1, 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* bad nesting in subparser */ | 
					
						
							|  |  |  | 	json = "{[]"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	expect_object(&it[0], &it[1]); | 
					
						
							|  |  |  | 	expect_array(&it[1], &it[2]); | 
					
						
							|  |  |  | 	expect_parse_error(&it[1], json, 1, 4); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* entered parser assumes nesting */ | 
					
						
							|  |  |  | 	json = "[]"; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	spa_json_enter(&it[0], &it[1]); | 
					
						
							|  |  |  | 	expect_array(&it[1], &it[2]); | 
					
						
							|  |  |  | 	expect_parse_error(&it[1], json, 1, 3); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* overflowing parser nesting stack */ | 
					
						
							|  |  |  | 	for (i = 0; i < 256; ++i) | 
					
						
							|  |  |  | 		buf[i] = '['; | 
					
						
							|  |  |  | 	for (; i < 511; ++i) | 
					
						
							|  |  |  | 		buf[i] = ']'; | 
					
						
							|  |  |  | 	buf[i++] = '}'; | 
					
						
							|  |  |  | 	buf[i++] = '\0'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spa_json_init(&it[0], buf, strlen(buf)); | 
					
						
							|  |  |  | 	pwtest_int_eq(spa_json_next(&it[0], &value), 1); | 
					
						
							|  |  |  | 	expect_parse_error(&it[0], buf, 1, strlen(buf)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* bad utf8 */ | 
					
						
							|  |  |  | 	json = "\"\xc0\""; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	expect_parse_error(&it[0], json, 1, 3); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	json = "\"\xe6\xad\""; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	expect_parse_error(&it[0], json, 1, 4); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	json = "\"\xf0\x92\x80\""; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	expect_parse_error(&it[0], json, 1, 5); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* bad string */ | 
					
						
							|  |  |  | 	json = "\"\x01\""; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	expect_parse_error(&it[0], json, 1, 2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	json = "\"\x0f\""; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	expect_parse_error(&it[0], json, 1, 2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* bad escape */ | 
					
						
							|  |  |  | 	json = "\"\\z\""; | 
					
						
							|  |  |  | 	spa_json_init(&it[0], json, strlen(json)); | 
					
						
							|  |  |  | 	expect_parse_error(&it[0], json, 1, 3); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return PWTEST_PASS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | PWTEST(json_encode) | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-01-04 12:35:09 +01:00
										 |  |  | 	char dst[128]; | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | 	char dst4[4]; | 
					
						
							|  |  |  | 	char dst6[6]; | 
					
						
							| 
									
										
										
										
											2021-03-11 19:03:42 +01:00
										 |  |  | 	char result[1024]; | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | 	pwtest_int_eq(spa_json_encode_string(dst, sizeof(dst), "test"), 6); | 
					
						
							|  |  |  | 	pwtest_str_eq(dst, "\"test\""); | 
					
						
							|  |  |  | 	pwtest_int_eq(spa_json_encode_string(dst4, sizeof(dst4), "test"), 6); | 
					
						
							|  |  |  | 	pwtest_int_eq(strncmp(dst4, "\"tes", 4), 0); | 
					
						
							|  |  |  | 	pwtest_int_eq(spa_json_encode_string(dst6, sizeof(dst6), "test"), 6); | 
					
						
							|  |  |  | 	pwtest_int_eq(strncmp(dst6, "\"test\"", 6), 0); | 
					
						
							|  |  |  | 	pwtest_int_eq(spa_json_encode_string(dst, sizeof(dst), "test\"\n\r \t\b\f\'"), 20); | 
					
						
							|  |  |  | 	pwtest_str_eq(dst, "\"test\\\"\\n\\r \\t\\b\\f'\""); | 
					
						
							|  |  |  | 	pwtest_int_eq(spa_json_encode_string(dst, sizeof(dst), "\x04\x05\x1f\x20\x01\x7f\x90"), 29); | 
					
						
							|  |  |  | 	pwtest_str_eq(dst, "\"\\u0004\\u0005\\u001f \\u0001\x7f\x90\""); | 
					
						
							| 
									
										
										
										
											2022-01-04 12:35:09 +01:00
										 |  |  | 	pwtest_int_eq(spa_json_parse_stringn(dst, sizeof(dst), result, sizeof(result)), 1); | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | 	pwtest_str_eq(result, "\x04\x05\x1f\x20\x01\x7f\x90"); | 
					
						
							| 
									
										
										
										
											2022-04-26 11:01:33 +02:00
										 |  |  | 	strcpy(dst, "\"\\u03b2a\""); | 
					
						
							|  |  |  | 	pwtest_int_eq(spa_json_parse_stringn(dst, sizeof(dst), result, sizeof(result)), 1); | 
					
						
							| 
									
										
										
										
											2022-04-26 15:38:22 +02:00
										 |  |  | 	pwtest_str_eq(result, "\316\262a"); | 
					
						
							| 
									
										
										
										
											2022-04-27 08:37:32 +02:00
										 |  |  | 	strcpy(dst, "\"\\u 03b2a \""); | 
					
						
							|  |  |  | 	pwtest_int_eq(spa_json_parse_stringn(dst, sizeof(dst), result, sizeof(result)), 1); | 
					
						
							|  |  |  | 	pwtest_str_eq(result, "u 03b2a "); | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return PWTEST_PASS; | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-16 17:47:35 +02:00
										 |  |  | static void test_array(const char *str, const char * const vals[]) | 
					
						
							| 
									
										
										
										
											2021-03-18 18:40:56 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct spa_json it[2]; | 
					
						
							|  |  |  | 	char val[256]; | 
					
						
							| 
									
										
										
										
											2021-03-18 18:57:26 +01:00
										 |  |  | 	int i; | 
					
						
							| 
									
										
										
										
											2021-03-18 18:40:56 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	spa_json_init(&it[0], str, strlen(str)); | 
					
						
							|  |  |  | 	if (spa_json_enter_array(&it[0], &it[1]) <= 0) | 
					
						
							|  |  |  | 		spa_json_init(&it[1], str, strlen(str)); | 
					
						
							|  |  |  | 	for (i = 0; vals[i]; i++) { | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | 		pwtest_int_gt(spa_json_get_string(&it[1], val, sizeof(val)), 0); | 
					
						
							|  |  |  | 		pwtest_str_eq(val, vals[i]); | 
					
						
							| 
									
										
										
										
											2021-03-18 18:40:56 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | PWTEST(json_array) | 
					
						
							| 
									
										
										
										
											2021-03-18 18:40:56 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-09-16 17:47:35 +02:00
										 |  |  | 	test_array("FL,FR", (const char *[]){ "FL", "FR", NULL }); | 
					
						
							|  |  |  | 	test_array(" FL , FR ", (const char *[]){ "FL", "FR", NULL }); | 
					
						
							|  |  |  | 	test_array("[ FL , FR ]", (const char *[]){ "FL", "FR", NULL }); | 
					
						
							|  |  |  | 	test_array("[FL FR]", (const char *[]){ "FL", "FR", NULL }); | 
					
						
							|  |  |  | 	test_array("FL FR", (const char *[]){ "FL", "FR", NULL }); | 
					
						
							|  |  |  | 	test_array("[ FL FR ]", (const char *[]){ "FL", "FR", NULL }); | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return PWTEST_PASS; | 
					
						
							| 
									
										
										
										
											2021-03-18 18:40:56 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | PWTEST(json_overflow) | 
					
						
							| 
									
										
										
										
											2021-03-18 19:44:25 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct spa_json it[2]; | 
					
						
							|  |  |  | 	char val[3]; | 
					
						
							|  |  |  | 	const char *str = "[ F, FR, FRC ]"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spa_json_init(&it[0], str, strlen(str)); | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | 	pwtest_int_gt(spa_json_enter_array(&it[0], &it[1]), 0); | 
					
						
							| 
									
										
										
										
											2021-03-18 19:44:25 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | 	pwtest_int_gt(spa_json_get_string(&it[1], val, sizeof(val)), 0); | 
					
						
							|  |  |  | 	pwtest_str_eq(val, "F"); | 
					
						
							|  |  |  | 	pwtest_int_gt(spa_json_get_string(&it[1], val, sizeof(val)), 0); | 
					
						
							|  |  |  | 	pwtest_str_eq(val, "FR"); | 
					
						
							|  |  |  | 	pwtest_int_lt(spa_json_get_string(&it[1], val, sizeof(val)), 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return PWTEST_PASS; | 
					
						
							| 
									
										
										
										
											2021-03-18 19:44:25 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-20 09:28:39 +01:00
										 |  |  | PWTEST(json_float) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-03-20 21:04:33 +01:00
										 |  |  | 	struct { | 
					
						
							|  |  |  | 		const char *str; | 
					
						
							|  |  |  | 		double val; | 
					
						
							|  |  |  | 	} val[] = { | 
					
						
							|  |  |  | 		{ "0.0", 0.0f }, | 
					
						
							|  |  |  | 		{ ".0", 0.0f }, | 
					
						
							|  |  |  | 		{ ".0E0", 0.0E0f }, | 
					
						
							|  |  |  | 		{ "1.0", 1.0f }, | 
					
						
							|  |  |  | 		{ "1.011", 1.011f }, | 
					
						
							|  |  |  | 		{ "176543.123456", 176543.123456f }, | 
					
						
							|  |  |  | 		{ "-176543.123456", -176543.123456f }, | 
					
						
							|  |  |  | 		{ "-5678.5432E10", -5678.5432E10f }, | 
					
						
							|  |  |  | 		{ "-5678.5432e10", -5678.5432e10f }, | 
					
						
							|  |  |  | 		{ "-5678.5432e-10", -5678.5432e-10f }, | 
					
						
							|  |  |  | 		{ "5678.5432e+10", 5678.5432e+10f }, | 
					
						
							|  |  |  | 		{ "00.000100", 00.000100f }, | 
					
						
							|  |  |  | 		{ "-0.000100", -0.000100f }, | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2022-03-20 09:28:39 +01:00
										 |  |  | 	float v; | 
					
						
							| 
									
										
										
										
											2022-03-20 21:04:33 +01:00
										 |  |  | 	unsigned i; | 
					
						
							| 
									
										
										
										
											2022-03-21 10:41:44 +01:00
										 |  |  | 	char buf1[128], buf2[128], *b1 = buf1, *b2 = buf2; | 
					
						
							| 
									
										
										
										
											2022-03-20 21:04:33 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-20 09:28:39 +01:00
										 |  |  | 	pwtest_int_eq(spa_json_parse_float("", 0, &v), 0); | 
					
						
							| 
									
										
										
										
											2022-03-20 21:04:33 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	setlocale(LC_NUMERIC, "C"); | 
					
						
							|  |  |  | 	for (i = 0; i < SPA_N_ELEMENTS(val); i++) { | 
					
						
							|  |  |  | 		pwtest_int_gt(spa_json_parse_float(val[i].str, strlen(val[i].str), &v), 0); | 
					
						
							|  |  |  | 		pwtest_double_eq(v, val[i].val); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	setlocale(LC_NUMERIC, "fr_FR"); | 
					
						
							|  |  |  | 	for (i = 0; i < SPA_N_ELEMENTS(val); i++) { | 
					
						
							|  |  |  | 		pwtest_int_gt(spa_json_parse_float(val[i].str, strlen(val[i].str), &v), 0); | 
					
						
							|  |  |  | 		pwtest_double_eq(v, val[i].val); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-03-21 10:41:44 +01:00
										 |  |  | 	pwtest_ptr_eq(spa_json_format_float(buf1, sizeof(buf1), 0.0f), b1); | 
					
						
							|  |  |  | 	pwtest_str_eq(buf1, "0.000000"); | 
					
						
							|  |  |  | 	pwtest_ptr_eq(spa_json_format_float(buf1, sizeof(buf1), NAN), b1); | 
					
						
							|  |  |  | 	pwtest_str_eq(buf1, "0.000000"); | 
					
						
							|  |  |  | 	pwtest_ptr_eq(spa_json_format_float(buf1, sizeof(buf1), INFINITY), b1); | 
					
						
							|  |  |  | 	pwtest_ptr_eq(spa_json_format_float(buf2, sizeof(buf2), FLT_MAX), b2); | 
					
						
							|  |  |  | 	pwtest_str_eq(buf1, buf2); | 
					
						
							|  |  |  | 	pwtest_ptr_eq(spa_json_format_float(buf1, sizeof(buf1), -INFINITY), b1); | 
					
						
							|  |  |  | 	pwtest_ptr_eq(spa_json_format_float(buf2, sizeof(buf2), FLT_MIN), b2); | 
					
						
							|  |  |  | 	pwtest_str_eq(buf1, buf2); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-20 09:28:39 +01:00
										 |  |  | 	return PWTEST_PASS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-11 12:05:42 +02:00
										 |  |  | PWTEST(json_float_check) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct { | 
					
						
							|  |  |  | 		const char *str; | 
					
						
							|  |  |  | 		int res; | 
					
						
							|  |  |  | 	} val[] = { | 
					
						
							|  |  |  | 		{ "0.0", 1 }, | 
					
						
							|  |  |  | 		{ ".0", 1 }, | 
					
						
							|  |  |  | 		{ "+.0E0", 1 }, | 
					
						
							|  |  |  | 		{ "-.0e0", 1 }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		{ "0,0", 0 }, | 
					
						
							|  |  |  | 		{ "0.0.5", 0 }, | 
					
						
							|  |  |  | 		{ "0x0", 0 }, | 
					
						
							|  |  |  | 		{ "0x0.0", 0 }, | 
					
						
							|  |  |  | 		{ "E10", 0 }, | 
					
						
							|  |  |  | 		{ "e20", 0 }, | 
					
						
							| 
									
										
										
										
											2022-07-11 12:15:40 +02:00
										 |  |  | 		{ " 0.0", 0 }, | 
					
						
							|  |  |  | 		{ "0.0 ", 0 }, | 
					
						
							|  |  |  | 		{ " 0.0 ", 0 }, | 
					
						
							| 
									
										
										
										
											2022-07-11 12:05:42 +02:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 	unsigned i; | 
					
						
							|  |  |  | 	float v; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < SPA_N_ELEMENTS(val); i++) { | 
					
						
							|  |  |  | 		pwtest_int_eq(spa_json_parse_float(val[i].str, strlen(val[i].str), &v), val[i].res); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return PWTEST_PASS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-20 09:28:39 +01:00
										 |  |  | PWTEST(json_int) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int v; | 
					
						
							|  |  |  | 	pwtest_int_eq(spa_json_parse_int("", 0, &v), 0); | 
					
						
							|  |  |  | 	return PWTEST_PASS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | PWTEST_SUITE(spa_json) | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | 	pwtest_add(json_abi, PWTEST_NOARG); | 
					
						
							|  |  |  | 	pwtest_add(json_parse, PWTEST_NOARG); | 
					
						
							| 
									
										
										
										
											2024-03-20 19:42:02 +02:00
										 |  |  | 	pwtest_add(json_parse_fail, PWTEST_NOARG); | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | 	pwtest_add(json_encode, PWTEST_NOARG); | 
					
						
							|  |  |  | 	pwtest_add(json_array, PWTEST_NOARG); | 
					
						
							|  |  |  | 	pwtest_add(json_overflow, PWTEST_NOARG); | 
					
						
							| 
									
										
										
										
											2022-03-20 09:28:39 +01:00
										 |  |  | 	pwtest_add(json_float, PWTEST_NOARG); | 
					
						
							| 
									
										
										
										
											2022-07-11 12:05:42 +02:00
										 |  |  | 	pwtest_add(json_float_check, PWTEST_NOARG); | 
					
						
							| 
									
										
										
										
											2022-03-20 09:28:39 +01:00
										 |  |  | 	pwtest_add(json_int, PWTEST_NOARG); | 
					
						
							| 
									
										
										
										
											2021-06-03 11:35:26 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return PWTEST_PASS; | 
					
						
							| 
									
										
										
										
											2020-11-28 15:34:01 +01:00
										 |  |  | } |