xref: /spdk/test/unit/lib/json/json_parse.c/json_parse_ut.c (revision ea941caeaf896fdf2aef7685f86f37023060faed)
1488570ebSJim Harris /*   SPDX-License-Identifier: BSD-3-Clause
2a6dbe372Spaul luse  *   Copyright (C) 2016 Intel Corporation.
3d57bf4ccSDaniel Verkamp  *   All rights reserved.
4d57bf4ccSDaniel Verkamp  */
5d57bf4ccSDaniel Verkamp 
6d57bf4ccSDaniel Verkamp #include "spdk/stdinc.h"
7d57bf4ccSDaniel Verkamp 
8ae431e31SKonrad Sztyber #include "spdk_internal/cunit.h"
9d57bf4ccSDaniel Verkamp 
10f8ad4dcaSJim Harris #include "json/json_parse.c"
11d57bf4ccSDaniel Verkamp 
12c8583472Stongkunkun #define JSONVALUE_NUM 100
13c8583472Stongkunkun 
14d57bf4ccSDaniel Verkamp static uint8_t g_buf[1000];
15d57bf4ccSDaniel Verkamp static void *g_end;
16c8583472Stongkunkun static struct spdk_json_val g_vals[JSONVALUE_NUM];
17d57bf4ccSDaniel Verkamp static int g_cur_val;
18d57bf4ccSDaniel Verkamp 
19d57bf4ccSDaniel Verkamp /* Fill buf with raw data */
20d57bf4ccSDaniel Verkamp #define BUF_SETUP(in) \
21d57bf4ccSDaniel Verkamp 	memset(g_buf, 0, sizeof(g_buf)); \
22d57bf4ccSDaniel Verkamp 	if (sizeof(in) > 1) { \
23d57bf4ccSDaniel Verkamp 		memcpy(g_buf, in, sizeof(in) - 1); \
24d57bf4ccSDaniel Verkamp 	} \
25d57bf4ccSDaniel Verkamp 	g_end = NULL
26d57bf4ccSDaniel Verkamp 
27d57bf4ccSDaniel Verkamp /*
28d57bf4ccSDaniel Verkamp  * Do two checks - first pass NULL for values to ensure the count is correct,
29d57bf4ccSDaniel Verkamp  *  then pass g_vals to get the actual values.
30d57bf4ccSDaniel Verkamp  */
31d57bf4ccSDaniel Verkamp #define PARSE_PASS_FLAGS(in, num_vals, trailing, flags) \
32d57bf4ccSDaniel Verkamp 	BUF_SETUP(in); \
33d57bf4ccSDaniel Verkamp 	CU_ASSERT(spdk_json_parse(g_buf, sizeof(in) - 1, NULL, 0, &g_end, flags) == num_vals); \
34d57bf4ccSDaniel Verkamp 	memset(g_vals, 0, sizeof(g_vals)); \
35c8583472Stongkunkun 	CU_ASSERT(spdk_json_parse(g_buf, sizeof(in) - 1, g_vals, JSONVALUE_NUM, &g_end, flags | SPDK_JSON_PARSE_FLAG_DECODE_IN_PLACE) == num_vals); \
36d57bf4ccSDaniel Verkamp 	CU_ASSERT(g_end == g_buf + sizeof(in) - sizeof(trailing)); \
37d57bf4ccSDaniel Verkamp 	CU_ASSERT(memcmp(g_end, trailing, sizeof(trailing) - 1) == 0); \
38d57bf4ccSDaniel Verkamp 	g_cur_val = 0
39d57bf4ccSDaniel Verkamp 
40d57bf4ccSDaniel Verkamp #define PARSE_PASS(in, num_vals, trailing) \
41d57bf4ccSDaniel Verkamp 	PARSE_PASS_FLAGS(in, num_vals, trailing, 0)
42d57bf4ccSDaniel Verkamp 
43d57bf4ccSDaniel Verkamp #define PARSE_FAIL_FLAGS(in, retval, flags) \
44d57bf4ccSDaniel Verkamp 	BUF_SETUP(in); \
45d57bf4ccSDaniel Verkamp 	CU_ASSERT(spdk_json_parse(g_buf, sizeof(in) - 1, NULL, 0, &g_end, flags) == retval)
46d57bf4ccSDaniel Verkamp 
47d57bf4ccSDaniel Verkamp #define PARSE_FAIL(in, retval) \
48d57bf4ccSDaniel Verkamp 	PARSE_FAIL_FLAGS(in, retval, 0)
49d57bf4ccSDaniel Verkamp 
50d57bf4ccSDaniel Verkamp #define VAL_STRING_MATCH(str, var_type) \
51d57bf4ccSDaniel Verkamp 	CU_ASSERT(g_vals[g_cur_val].type == var_type); \
52d57bf4ccSDaniel Verkamp 	CU_ASSERT(g_vals[g_cur_val].len == sizeof(str) - 1); \
53d57bf4ccSDaniel Verkamp 	if (g_vals[g_cur_val].len == sizeof(str) - 1 && sizeof(str) > 1) { \
54d57bf4ccSDaniel Verkamp 		CU_ASSERT(memcmp(g_vals[g_cur_val].start, str, g_vals[g_cur_val].len) == 0); \
55d57bf4ccSDaniel Verkamp 	} \
56d57bf4ccSDaniel Verkamp 	g_cur_val++
57d57bf4ccSDaniel Verkamp 
58d57bf4ccSDaniel Verkamp #define VAL_STRING(str) VAL_STRING_MATCH(str, SPDK_JSON_VAL_STRING)
59d57bf4ccSDaniel Verkamp #define VAL_NAME(str) VAL_STRING_MATCH(str, SPDK_JSON_VAL_NAME)
60d57bf4ccSDaniel Verkamp #define VAL_NUMBER(num) VAL_STRING_MATCH(num, SPDK_JSON_VAL_NUMBER)
61d57bf4ccSDaniel Verkamp 
62d57bf4ccSDaniel Verkamp #define VAL_LITERAL(str, val_type) \
63d57bf4ccSDaniel Verkamp 	CU_ASSERT(g_vals[g_cur_val].type == val_type); \
64d57bf4ccSDaniel Verkamp 	CU_ASSERT(g_vals[g_cur_val].len == strlen(str)); \
65d57bf4ccSDaniel Verkamp 	if (g_vals[g_cur_val].len == strlen(str)) { \
66d57bf4ccSDaniel Verkamp 		CU_ASSERT(memcmp(g_vals[g_cur_val].start, str, g_vals[g_cur_val].len) == 0); \
67d57bf4ccSDaniel Verkamp 	} \
68d57bf4ccSDaniel Verkamp 	g_cur_val++
69d57bf4ccSDaniel Verkamp 
70d57bf4ccSDaniel Verkamp #define VAL_TRUE() VAL_LITERAL("true", SPDK_JSON_VAL_TRUE)
71d57bf4ccSDaniel Verkamp #define VAL_FALSE() VAL_LITERAL("false", SPDK_JSON_VAL_FALSE)
72d57bf4ccSDaniel Verkamp #define VAL_NULL() VAL_LITERAL("null", SPDK_JSON_VAL_NULL)
73d57bf4ccSDaniel Verkamp 
74d57bf4ccSDaniel Verkamp #define VAL_ARRAY_BEGIN(count) \
75d57bf4ccSDaniel Verkamp 	CU_ASSERT(g_vals[g_cur_val].type == SPDK_JSON_VAL_ARRAY_BEGIN); \
76d57bf4ccSDaniel Verkamp 	CU_ASSERT(g_vals[g_cur_val].len == count); \
77d57bf4ccSDaniel Verkamp 	g_cur_val++
78d57bf4ccSDaniel Verkamp 
79d57bf4ccSDaniel Verkamp #define VAL_ARRAY_END() \
80d57bf4ccSDaniel Verkamp 	CU_ASSERT(g_vals[g_cur_val].type == SPDK_JSON_VAL_ARRAY_END); \
81d57bf4ccSDaniel Verkamp 	g_cur_val++
82d57bf4ccSDaniel Verkamp 
83d57bf4ccSDaniel Verkamp #define VAL_OBJECT_BEGIN(count) \
84d57bf4ccSDaniel Verkamp 	CU_ASSERT(g_vals[g_cur_val].type == SPDK_JSON_VAL_OBJECT_BEGIN); \
85d57bf4ccSDaniel Verkamp 	CU_ASSERT(g_vals[g_cur_val].len == count); \
86d57bf4ccSDaniel Verkamp 	g_cur_val++
87d57bf4ccSDaniel Verkamp 
88d57bf4ccSDaniel Verkamp #define VAL_OBJECT_END() \
89d57bf4ccSDaniel Verkamp 	CU_ASSERT(g_vals[g_cur_val].type == SPDK_JSON_VAL_OBJECT_END); \
90d57bf4ccSDaniel Verkamp 	g_cur_val++
91d57bf4ccSDaniel Verkamp 
92d57bf4ccSDaniel Verkamp /* Simplified macros for string-only testing */
93d57bf4ccSDaniel Verkamp #define STR_PASS(in, out) \
94d57bf4ccSDaniel Verkamp 	PARSE_PASS("\"" in "\"", 1, ""); \
95d57bf4ccSDaniel Verkamp 	VAL_STRING(out)
96d57bf4ccSDaniel Verkamp 
97d57bf4ccSDaniel Verkamp #define STR_FAIL(in, retval) \
98d57bf4ccSDaniel Verkamp 	PARSE_FAIL("\"" in "\"", retval)
99d57bf4ccSDaniel Verkamp 
100d57bf4ccSDaniel Verkamp /* Simplified macros for number-only testing (no whitespace allowed) */
101d57bf4ccSDaniel Verkamp #define NUM_PASS(in) \
102d57bf4ccSDaniel Verkamp 	PARSE_PASS(in, 1, ""); \
103d57bf4ccSDaniel Verkamp 	VAL_NUMBER(in)
104d57bf4ccSDaniel Verkamp 
105d57bf4ccSDaniel Verkamp #define NUM_FAIL(in, retval) \
106d57bf4ccSDaniel Verkamp 	PARSE_FAIL(in, retval)
107d57bf4ccSDaniel Verkamp 
108d57bf4ccSDaniel Verkamp static void
test_parse_literal(void)109d57bf4ccSDaniel Verkamp test_parse_literal(void)
110d57bf4ccSDaniel Verkamp {
111d57bf4ccSDaniel Verkamp 	PARSE_PASS("true", 1, "");
112d57bf4ccSDaniel Verkamp 	VAL_TRUE();
113d57bf4ccSDaniel Verkamp 
114d57bf4ccSDaniel Verkamp 	PARSE_PASS("  true  ", 1, "");
115d57bf4ccSDaniel Verkamp 	VAL_TRUE();
116d57bf4ccSDaniel Verkamp 
117d57bf4ccSDaniel Verkamp 	PARSE_PASS("false", 1, "");
118d57bf4ccSDaniel Verkamp 	VAL_FALSE();
119d57bf4ccSDaniel Verkamp 
120d57bf4ccSDaniel Verkamp 	PARSE_PASS("null", 1, "");
121d57bf4ccSDaniel Verkamp 	VAL_NULL();
122d57bf4ccSDaniel Verkamp 
123d57bf4ccSDaniel Verkamp 	PARSE_PASS("trueaaa", 1, "aaa");
124d57bf4ccSDaniel Verkamp 	VAL_TRUE();
125d57bf4ccSDaniel Verkamp 
126d57bf4ccSDaniel Verkamp 	PARSE_PASS("truefalse", 1, "false");
127d57bf4ccSDaniel Verkamp 	VAL_TRUE();
128d57bf4ccSDaniel Verkamp 
129d57bf4ccSDaniel Verkamp 	PARSE_PASS("true false", 1, "false");
130d57bf4ccSDaniel Verkamp 	VAL_TRUE();
131d57bf4ccSDaniel Verkamp 
132d57bf4ccSDaniel Verkamp 	PARSE_PASS("true,false", 1, ",false");
133d57bf4ccSDaniel Verkamp 	VAL_TRUE();
134d57bf4ccSDaniel Verkamp 
135d57bf4ccSDaniel Verkamp 	PARSE_PASS("true,", 1, ",");
136d57bf4ccSDaniel Verkamp 	VAL_TRUE();
137d57bf4ccSDaniel Verkamp 
138d57bf4ccSDaniel Verkamp 	PARSE_FAIL("True", SPDK_JSON_PARSE_INVALID);
139d57bf4ccSDaniel Verkamp 	PARSE_FAIL("abcdef", SPDK_JSON_PARSE_INVALID);
140d57bf4ccSDaniel Verkamp 
141d57bf4ccSDaniel Verkamp 	PARSE_FAIL("t", SPDK_JSON_PARSE_INCOMPLETE);
142d57bf4ccSDaniel Verkamp 	PARSE_FAIL("tru", SPDK_JSON_PARSE_INCOMPLETE);
143d57bf4ccSDaniel Verkamp 	PARSE_FAIL("f", SPDK_JSON_PARSE_INCOMPLETE);
144d57bf4ccSDaniel Verkamp 	PARSE_FAIL("fals", SPDK_JSON_PARSE_INCOMPLETE);
145d57bf4ccSDaniel Verkamp 	PARSE_FAIL("n", SPDK_JSON_PARSE_INCOMPLETE);
146d57bf4ccSDaniel Verkamp 	PARSE_FAIL("nul", SPDK_JSON_PARSE_INCOMPLETE);
147ad51b333SDaniel Verkamp 
148ad51b333SDaniel Verkamp 	PARSE_FAIL("taaaaa", SPDK_JSON_PARSE_INVALID);
149ad51b333SDaniel Verkamp 	PARSE_FAIL("faaaaa", SPDK_JSON_PARSE_INVALID);
150ad51b333SDaniel Verkamp 	PARSE_FAIL("naaaaa", SPDK_JSON_PARSE_INVALID);
151d57bf4ccSDaniel Verkamp }
152d57bf4ccSDaniel Verkamp 
153d57bf4ccSDaniel Verkamp static void
test_parse_string_simple(void)154d57bf4ccSDaniel Verkamp test_parse_string_simple(void)
155d57bf4ccSDaniel Verkamp {
156d57bf4ccSDaniel Verkamp 	PARSE_PASS("\"\"", 1, "");
157d57bf4ccSDaniel Verkamp 	VAL_STRING("");
158d57bf4ccSDaniel Verkamp 
159d57bf4ccSDaniel Verkamp 	PARSE_PASS("\"hello world\"", 1, "");
160d57bf4ccSDaniel Verkamp 	VAL_STRING("hello world");
161d57bf4ccSDaniel Verkamp 
162d57bf4ccSDaniel Verkamp 	PARSE_PASS("     \"hello world\"     ", 1, "");
163d57bf4ccSDaniel Verkamp 	VAL_STRING("hello world");
164d57bf4ccSDaniel Verkamp 
165d57bf4ccSDaniel Verkamp 	/* Unterminated string */
166d57bf4ccSDaniel Verkamp 	PARSE_FAIL("\"hello world", SPDK_JSON_PARSE_INCOMPLETE);
167d57bf4ccSDaniel Verkamp 
168d57bf4ccSDaniel Verkamp 	/* Trailing comma */
169d57bf4ccSDaniel Verkamp 	PARSE_PASS("\"hello world\",", 1, ",");
170d57bf4ccSDaniel Verkamp 	VAL_STRING("hello world");
171d57bf4ccSDaniel Verkamp }
172d57bf4ccSDaniel Verkamp 
173d57bf4ccSDaniel Verkamp static void
test_parse_string_control_chars(void)174d57bf4ccSDaniel Verkamp test_parse_string_control_chars(void)
175d57bf4ccSDaniel Verkamp {
176d57bf4ccSDaniel Verkamp 	/* U+0000 through U+001F must be escaped */
177d57bf4ccSDaniel Verkamp 	STR_FAIL("\x00", SPDK_JSON_PARSE_INVALID);
178d57bf4ccSDaniel Verkamp 	STR_FAIL("\x01", SPDK_JSON_PARSE_INVALID);
179d57bf4ccSDaniel Verkamp 	STR_FAIL("\x02", SPDK_JSON_PARSE_INVALID);
180d57bf4ccSDaniel Verkamp 	STR_FAIL("\x03", SPDK_JSON_PARSE_INVALID);
181d57bf4ccSDaniel Verkamp 	STR_FAIL("\x04", SPDK_JSON_PARSE_INVALID);
182d57bf4ccSDaniel Verkamp 	STR_FAIL("\x05", SPDK_JSON_PARSE_INVALID);
183d57bf4ccSDaniel Verkamp 	STR_FAIL("\x06", SPDK_JSON_PARSE_INVALID);
184d57bf4ccSDaniel Verkamp 	STR_FAIL("\x07", SPDK_JSON_PARSE_INVALID);
185d57bf4ccSDaniel Verkamp 	STR_FAIL("\x08", SPDK_JSON_PARSE_INVALID);
186d57bf4ccSDaniel Verkamp 	STR_FAIL("\x09", SPDK_JSON_PARSE_INVALID);
187d57bf4ccSDaniel Verkamp 	STR_FAIL("\x0A", SPDK_JSON_PARSE_INVALID);
188d57bf4ccSDaniel Verkamp 	STR_FAIL("\x0B", SPDK_JSON_PARSE_INVALID);
189d57bf4ccSDaniel Verkamp 	STR_FAIL("\x0C", SPDK_JSON_PARSE_INVALID);
190d57bf4ccSDaniel Verkamp 	STR_FAIL("\x0D", SPDK_JSON_PARSE_INVALID);
191d57bf4ccSDaniel Verkamp 	STR_FAIL("\x0E", SPDK_JSON_PARSE_INVALID);
192d57bf4ccSDaniel Verkamp 	STR_FAIL("\x0F", SPDK_JSON_PARSE_INVALID);
193d57bf4ccSDaniel Verkamp 	STR_FAIL("\x10", SPDK_JSON_PARSE_INVALID);
194d57bf4ccSDaniel Verkamp 	STR_FAIL("\x11", SPDK_JSON_PARSE_INVALID);
195d57bf4ccSDaniel Verkamp 	STR_FAIL("\x12", SPDK_JSON_PARSE_INVALID);
196d57bf4ccSDaniel Verkamp 	STR_FAIL("\x13", SPDK_JSON_PARSE_INVALID);
197d57bf4ccSDaniel Verkamp 	STR_FAIL("\x14", SPDK_JSON_PARSE_INVALID);
198d57bf4ccSDaniel Verkamp 	STR_FAIL("\x15", SPDK_JSON_PARSE_INVALID);
199d57bf4ccSDaniel Verkamp 	STR_FAIL("\x16", SPDK_JSON_PARSE_INVALID);
200d57bf4ccSDaniel Verkamp 	STR_FAIL("\x17", SPDK_JSON_PARSE_INVALID);
201d57bf4ccSDaniel Verkamp 	STR_FAIL("\x18", SPDK_JSON_PARSE_INVALID);
202d57bf4ccSDaniel Verkamp 	STR_FAIL("\x19", SPDK_JSON_PARSE_INVALID);
203d57bf4ccSDaniel Verkamp 	STR_FAIL("\x1A", SPDK_JSON_PARSE_INVALID);
204d57bf4ccSDaniel Verkamp 	STR_FAIL("\x1B", SPDK_JSON_PARSE_INVALID);
205d57bf4ccSDaniel Verkamp 	STR_FAIL("\x1C", SPDK_JSON_PARSE_INVALID);
206d57bf4ccSDaniel Verkamp 	STR_FAIL("\x1D", SPDK_JSON_PARSE_INVALID);
207d57bf4ccSDaniel Verkamp 	STR_FAIL("\x1E", SPDK_JSON_PARSE_INVALID);
208d57bf4ccSDaniel Verkamp 	STR_FAIL("\x1F", SPDK_JSON_PARSE_INVALID);
209d57bf4ccSDaniel Verkamp 	STR_PASS(" ", " "); /* \x20 (first valid unescaped char) */
210d57bf4ccSDaniel Verkamp 
211d57bf4ccSDaniel Verkamp 	/* Test control chars in the middle of a string */
212d57bf4ccSDaniel Verkamp 	STR_FAIL("abc\ndef", SPDK_JSON_PARSE_INVALID);
213d57bf4ccSDaniel Verkamp 	STR_FAIL("abc\tdef", SPDK_JSON_PARSE_INVALID);
214d57bf4ccSDaniel Verkamp }
215d57bf4ccSDaniel Verkamp 
216d57bf4ccSDaniel Verkamp static void
test_parse_string_utf8(void)217d57bf4ccSDaniel Verkamp test_parse_string_utf8(void)
218d57bf4ccSDaniel Verkamp {
219d57bf4ccSDaniel Verkamp 	/* Valid one-, two-, three-, and four-byte sequences */
220d57bf4ccSDaniel Verkamp 	STR_PASS("\x41", "A");
221d57bf4ccSDaniel Verkamp 	STR_PASS("\xC3\xB6", "\xC3\xB6");
222d57bf4ccSDaniel Verkamp 	STR_PASS("\xE2\x88\x9A", "\xE2\x88\x9A");
223d57bf4ccSDaniel Verkamp 	STR_PASS("\xF0\xA0\x9C\x8E", "\xF0\xA0\x9C\x8E");
224d57bf4ccSDaniel Verkamp 
225d57bf4ccSDaniel Verkamp 	/* Examples from RFC 3629 */
226d57bf4ccSDaniel Verkamp 	STR_PASS("\x41\xE2\x89\xA2\xCE\x91\x2E", "\x41\xE2\x89\xA2\xCE\x91\x2E");
227d57bf4ccSDaniel Verkamp 	STR_PASS("\xED\x95\x9C\xEA\xB5\xAD\xEC\x96\xB4", "\xED\x95\x9C\xEA\xB5\xAD\xEC\x96\xB4");
228d57bf4ccSDaniel Verkamp 	STR_PASS("\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E", "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E");
229d57bf4ccSDaniel Verkamp 	STR_PASS("\xEF\xBB\xBF\xF0\xA3\x8E\xB4", "\xEF\xBB\xBF\xF0\xA3\x8E\xB4");
230d57bf4ccSDaniel Verkamp 
231d57bf4ccSDaniel Verkamp 	/* Edge cases */
232d57bf4ccSDaniel Verkamp 	STR_PASS("\x7F", "\x7F");
233d57bf4ccSDaniel Verkamp 	STR_FAIL("\x80", SPDK_JSON_PARSE_INVALID);
234d57bf4ccSDaniel Verkamp 	STR_FAIL("\xC1", SPDK_JSON_PARSE_INVALID);
235d57bf4ccSDaniel Verkamp 	STR_FAIL("\xC2", SPDK_JSON_PARSE_INVALID);
236d57bf4ccSDaniel Verkamp 	STR_PASS("\xC2\x80", "\xC2\x80");
237d57bf4ccSDaniel Verkamp 	STR_PASS("\xC2\xBF", "\xC2\xBF");
238d57bf4ccSDaniel Verkamp 	STR_PASS("\xDF\x80", "\xDF\x80");
239d57bf4ccSDaniel Verkamp 	STR_PASS("\xDF\xBF", "\xDF\xBF");
240d57bf4ccSDaniel Verkamp 	STR_FAIL("\xDF", SPDK_JSON_PARSE_INVALID);
241d57bf4ccSDaniel Verkamp 	STR_FAIL("\xE0\x80", SPDK_JSON_PARSE_INVALID);
242d57bf4ccSDaniel Verkamp 	STR_FAIL("\xE0\x1F", SPDK_JSON_PARSE_INVALID);
243d57bf4ccSDaniel Verkamp 	STR_FAIL("\xE0\x1F\x80", SPDK_JSON_PARSE_INVALID);
244d57bf4ccSDaniel Verkamp 	STR_FAIL("\xE0", SPDK_JSON_PARSE_INVALID);
245d57bf4ccSDaniel Verkamp 	STR_FAIL("\xE0\xA0", SPDK_JSON_PARSE_INVALID);
246d57bf4ccSDaniel Verkamp 	STR_PASS("\xE0\xA0\x80", "\xE0\xA0\x80");
247d57bf4ccSDaniel Verkamp 	STR_PASS("\xE0\xA0\xBF", "\xE0\xA0\xBF");
248d57bf4ccSDaniel Verkamp 	STR_FAIL("\xE0\xA0\xC0", SPDK_JSON_PARSE_INVALID);
249d57bf4ccSDaniel Verkamp 	STR_PASS("\xE0\xBF\x80", "\xE0\xBF\x80");
250d57bf4ccSDaniel Verkamp 	STR_PASS("\xE0\xBF\xBF", "\xE0\xBF\xBF");
251d57bf4ccSDaniel Verkamp 	STR_FAIL("\xE0\xC0\x80", SPDK_JSON_PARSE_INVALID);
252d57bf4ccSDaniel Verkamp 	STR_FAIL("\xE1", SPDK_JSON_PARSE_INVALID);
253d57bf4ccSDaniel Verkamp 	STR_FAIL("\xE1\x80", SPDK_JSON_PARSE_INVALID);
254d57bf4ccSDaniel Verkamp 	STR_FAIL("\xE1\x7F\x80", SPDK_JSON_PARSE_INVALID);
255d57bf4ccSDaniel Verkamp 	STR_FAIL("\xE1\x80\x7F", SPDK_JSON_PARSE_INVALID);
256d57bf4ccSDaniel Verkamp 	STR_PASS("\xE1\x80\x80", "\xE1\x80\x80");
257d57bf4ccSDaniel Verkamp 	STR_PASS("\xE1\x80\xBF", "\xE1\x80\xBF");
258d57bf4ccSDaniel Verkamp 	STR_PASS("\xE1\xBF\x80", "\xE1\xBF\x80");
259d57bf4ccSDaniel Verkamp 	STR_PASS("\xE1\xBF\xBF", "\xE1\xBF\xBF");
260d57bf4ccSDaniel Verkamp 	STR_FAIL("\xE1\xC0\x80", SPDK_JSON_PARSE_INVALID);
261d57bf4ccSDaniel Verkamp 	STR_FAIL("\xE1\x80\xC0", SPDK_JSON_PARSE_INVALID);
262d57bf4ccSDaniel Verkamp 	STR_PASS("\xEF\x80\x80", "\xEF\x80\x80");
263d57bf4ccSDaniel Verkamp 	STR_PASS("\xEF\xBF\xBF", "\xEF\xBF\xBF");
264d57bf4ccSDaniel Verkamp 	STR_FAIL("\xF0", SPDK_JSON_PARSE_INVALID);
265d57bf4ccSDaniel Verkamp 	STR_FAIL("\xF0\x90", SPDK_JSON_PARSE_INVALID);
266d57bf4ccSDaniel Verkamp 	STR_FAIL("\xF0\x90\x80", SPDK_JSON_PARSE_INVALID);
267d57bf4ccSDaniel Verkamp 	STR_FAIL("\xF0\x80\x80\x80", SPDK_JSON_PARSE_INVALID);
268d57bf4ccSDaniel Verkamp 	STR_FAIL("\xF0\x8F\x80\x80", SPDK_JSON_PARSE_INVALID);
269d57bf4ccSDaniel Verkamp 	STR_PASS("\xF0\x90\x80\x80", "\xF0\x90\x80\x80");
270d57bf4ccSDaniel Verkamp 	STR_PASS("\xF0\x90\x80\xBF", "\xF0\x90\x80\xBF");
271d57bf4ccSDaniel Verkamp 	STR_PASS("\xF0\x90\xBF\x80", "\xF0\x90\xBF\x80");
272d57bf4ccSDaniel Verkamp 	STR_PASS("\xF0\xBF\x80\x80", "\xF0\xBF\x80\x80");
273d57bf4ccSDaniel Verkamp 	STR_FAIL("\xF0\xC0\x80\x80", SPDK_JSON_PARSE_INVALID);
274d57bf4ccSDaniel Verkamp 	STR_FAIL("\xF1", SPDK_JSON_PARSE_INVALID);
275d57bf4ccSDaniel Verkamp 	STR_FAIL("\xF1\x80", SPDK_JSON_PARSE_INVALID);
276d57bf4ccSDaniel Verkamp 	STR_FAIL("\xF1\x80\x80", SPDK_JSON_PARSE_INVALID);
277d57bf4ccSDaniel Verkamp 	STR_FAIL("\xF1\x80\x80\x7F", SPDK_JSON_PARSE_INVALID);
278d57bf4ccSDaniel Verkamp 	STR_PASS("\xF1\x80\x80\x80", "\xF1\x80\x80\x80");
279d57bf4ccSDaniel Verkamp 	STR_PASS("\xF1\x80\x80\xBF", "\xF1\x80\x80\xBF");
280d57bf4ccSDaniel Verkamp 	STR_PASS("\xF1\x80\xBF\x80", "\xF1\x80\xBF\x80");
281d57bf4ccSDaniel Verkamp 	STR_PASS("\xF1\xBF\x80\x80", "\xF1\xBF\x80\x80");
282d57bf4ccSDaniel Verkamp 	STR_PASS("\xF3\x80\x80\x80", "\xF3\x80\x80\x80");
283d57bf4ccSDaniel Verkamp 	STR_FAIL("\xF3\xC0\x80\x80", SPDK_JSON_PARSE_INVALID);
284d57bf4ccSDaniel Verkamp 	STR_FAIL("\xF3\x80\xC0\x80", SPDK_JSON_PARSE_INVALID);
285d57bf4ccSDaniel Verkamp 	STR_FAIL("\xF3\x80\x80\xC0", SPDK_JSON_PARSE_INVALID);
286d57bf4ccSDaniel Verkamp 	STR_FAIL("\xF4", SPDK_JSON_PARSE_INVALID);
287d57bf4ccSDaniel Verkamp 	STR_FAIL("\xF4\x80", SPDK_JSON_PARSE_INVALID);
288d57bf4ccSDaniel Verkamp 	STR_FAIL("\xF4\x80\x80", SPDK_JSON_PARSE_INVALID);
289d57bf4ccSDaniel Verkamp 	STR_PASS("\xF4\x80\x80\x80", "\xF4\x80\x80\x80");
290d57bf4ccSDaniel Verkamp 	STR_PASS("\xF4\x8F\x80\x80", "\xF4\x8F\x80\x80");
291d57bf4ccSDaniel Verkamp 	STR_PASS("\xF4\x8F\xBF\xBF", "\xF4\x8F\xBF\xBF");
292d57bf4ccSDaniel Verkamp 	STR_FAIL("\xF4\x90\x80\x80", SPDK_JSON_PARSE_INVALID);
293d57bf4ccSDaniel Verkamp 	STR_FAIL("\xF5", SPDK_JSON_PARSE_INVALID);
294d57bf4ccSDaniel Verkamp 	STR_FAIL("\xF5\x80", SPDK_JSON_PARSE_INVALID);
295d57bf4ccSDaniel Verkamp 	STR_FAIL("\xF5\x80\x80", SPDK_JSON_PARSE_INVALID);
296d57bf4ccSDaniel Verkamp 	STR_FAIL("\xF5\x80\x80\x80", SPDK_JSON_PARSE_INVALID);
297d57bf4ccSDaniel Verkamp 	STR_FAIL("\xF5\x80\x80\x80\x80", SPDK_JSON_PARSE_INVALID);
298d57bf4ccSDaniel Verkamp 
299d57bf4ccSDaniel Verkamp 	/* Overlong encodings */
300d57bf4ccSDaniel Verkamp 	STR_FAIL("\xC0\x80", SPDK_JSON_PARSE_INVALID);
301d57bf4ccSDaniel Verkamp 
302d57bf4ccSDaniel Verkamp 	/* Surrogate pairs */
303d57bf4ccSDaniel Verkamp 	STR_FAIL("\xED\xA0\x80", SPDK_JSON_PARSE_INVALID); /* U+D800 First high surrogate */
304d57bf4ccSDaniel Verkamp 	STR_FAIL("\xED\xAF\xBF", SPDK_JSON_PARSE_INVALID); /* U+DBFF Last high surrogate */
305d57bf4ccSDaniel Verkamp 	STR_FAIL("\xED\xB0\x80", SPDK_JSON_PARSE_INVALID); /* U+DC00 First low surrogate */
306d57bf4ccSDaniel Verkamp 	STR_FAIL("\xED\xBF\xBF", SPDK_JSON_PARSE_INVALID); /* U+DFFF Last low surrogate */
307d57bf4ccSDaniel Verkamp 	STR_FAIL("\xED\xA1\x8C\xED\xBE\xB4",
308d57bf4ccSDaniel Verkamp 		 SPDK_JSON_PARSE_INVALID); /* U+233B4 (invalid surrogate pair encoding) */
309d57bf4ccSDaniel Verkamp }
310d57bf4ccSDaniel Verkamp 
311d57bf4ccSDaniel Verkamp static void
test_parse_string_escapes_twochar(void)312d57bf4ccSDaniel Verkamp test_parse_string_escapes_twochar(void)
313d57bf4ccSDaniel Verkamp {
314d57bf4ccSDaniel Verkamp 	STR_PASS("\\\"", "\"");
315d57bf4ccSDaniel Verkamp 	STR_PASS("\\\\", "\\");
316d57bf4ccSDaniel Verkamp 	STR_PASS("\\/", "/");
317d57bf4ccSDaniel Verkamp 	STR_PASS("\\b", "\b");
318d57bf4ccSDaniel Verkamp 	STR_PASS("\\f", "\f");
319d57bf4ccSDaniel Verkamp 	STR_PASS("\\n", "\n");
320d57bf4ccSDaniel Verkamp 	STR_PASS("\\r", "\r");
321d57bf4ccSDaniel Verkamp 	STR_PASS("\\t", "\t");
322d57bf4ccSDaniel Verkamp 
323d57bf4ccSDaniel Verkamp 	STR_PASS("abc\\tdef", "abc\tdef");
324d57bf4ccSDaniel Verkamp 	STR_PASS("abc\\\"def", "abc\"def");
325d57bf4ccSDaniel Verkamp 
326d57bf4ccSDaniel Verkamp 	/* Backslash at end of string (will be treated as escaped quote) */
327d57bf4ccSDaniel Verkamp 	STR_FAIL("\\", SPDK_JSON_PARSE_INCOMPLETE);
328d57bf4ccSDaniel Verkamp 	STR_FAIL("abc\\", SPDK_JSON_PARSE_INCOMPLETE);
329d57bf4ccSDaniel Verkamp 
330d57bf4ccSDaniel Verkamp 	/* Invalid C-like escapes */
331d57bf4ccSDaniel Verkamp 	STR_FAIL("\\a", SPDK_JSON_PARSE_INVALID);
332d57bf4ccSDaniel Verkamp 	STR_FAIL("\\v", SPDK_JSON_PARSE_INVALID);
333d57bf4ccSDaniel Verkamp 	STR_FAIL("\\'", SPDK_JSON_PARSE_INVALID);
334d57bf4ccSDaniel Verkamp 	STR_FAIL("\\?", SPDK_JSON_PARSE_INVALID);
335d57bf4ccSDaniel Verkamp 	STR_FAIL("\\0", SPDK_JSON_PARSE_INVALID);
336d57bf4ccSDaniel Verkamp 	STR_FAIL("\\x00", SPDK_JSON_PARSE_INVALID);
337d57bf4ccSDaniel Verkamp 
338d57bf4ccSDaniel Verkamp 	/* Other invalid escapes */
339d57bf4ccSDaniel Verkamp 	STR_FAIL("\\B", SPDK_JSON_PARSE_INVALID);
340d57bf4ccSDaniel Verkamp 	STR_FAIL("\\z", SPDK_JSON_PARSE_INVALID);
341d57bf4ccSDaniel Verkamp }
342d57bf4ccSDaniel Verkamp 
343d57bf4ccSDaniel Verkamp static void
test_parse_string_escapes_unicode(void)344d57bf4ccSDaniel Verkamp test_parse_string_escapes_unicode(void)
345d57bf4ccSDaniel Verkamp {
346d57bf4ccSDaniel Verkamp 	STR_PASS("\\u0000", "\0");
347d57bf4ccSDaniel Verkamp 	STR_PASS("\\u0001", "\1");
348d57bf4ccSDaniel Verkamp 	STR_PASS("\\u0041", "A");
349d57bf4ccSDaniel Verkamp 	STR_PASS("\\uAAAA", "\xEA\xAA\xAA");
350d57bf4ccSDaniel Verkamp 	STR_PASS("\\uaaaa", "\xEA\xAA\xAA");
351d57bf4ccSDaniel Verkamp 	STR_PASS("\\uAaAa", "\xEA\xAA\xAA");
352d57bf4ccSDaniel Verkamp 
353d57bf4ccSDaniel Verkamp 	STR_FAIL("\\u", SPDK_JSON_PARSE_INVALID);
354d57bf4ccSDaniel Verkamp 	STR_FAIL("\\u0", SPDK_JSON_PARSE_INVALID);
355d57bf4ccSDaniel Verkamp 	STR_FAIL("\\u00", SPDK_JSON_PARSE_INVALID);
356d57bf4ccSDaniel Verkamp 	STR_FAIL("\\u000", SPDK_JSON_PARSE_INVALID);
357d57bf4ccSDaniel Verkamp 	STR_FAIL("\\u000g", SPDK_JSON_PARSE_INVALID);
358d57bf4ccSDaniel Verkamp 	STR_FAIL("\\U", SPDK_JSON_PARSE_INVALID);
359d57bf4ccSDaniel Verkamp 	STR_FAIL("\\U0000", SPDK_JSON_PARSE_INVALID);
360d57bf4ccSDaniel Verkamp 
361d57bf4ccSDaniel Verkamp 	PARSE_FAIL("\"\\u", SPDK_JSON_PARSE_INCOMPLETE);
362d57bf4ccSDaniel Verkamp 	PARSE_FAIL("\"\\u0", SPDK_JSON_PARSE_INCOMPLETE);
363d57bf4ccSDaniel Verkamp 	PARSE_FAIL("\"\\u00", SPDK_JSON_PARSE_INCOMPLETE);
364d57bf4ccSDaniel Verkamp 	PARSE_FAIL("\"\\u000", SPDK_JSON_PARSE_INCOMPLETE);
365d57bf4ccSDaniel Verkamp 
366d57bf4ccSDaniel Verkamp 	/* Surrogate pair */
367d57bf4ccSDaniel Verkamp 	STR_PASS("\\uD834\\uDD1E", "\xF0\x9D\x84\x9E");
368d57bf4ccSDaniel Verkamp 
369d57bf4ccSDaniel Verkamp 	/* Low surrogate without high */
370d57bf4ccSDaniel Verkamp 	STR_FAIL("\\uDC00", SPDK_JSON_PARSE_INVALID);
371d57bf4ccSDaniel Verkamp 	STR_FAIL("\\uDC00\\uDC00", SPDK_JSON_PARSE_INVALID);
372d57bf4ccSDaniel Verkamp 	STR_FAIL("\\uDC00abcdef", SPDK_JSON_PARSE_INVALID);
373d57bf4ccSDaniel Verkamp 	STR_FAIL("\\uDEAD", SPDK_JSON_PARSE_INVALID);
374d57bf4ccSDaniel Verkamp 	PARSE_FAIL("\"\\uD834", SPDK_JSON_PARSE_INCOMPLETE);
375d57bf4ccSDaniel Verkamp 	PARSE_FAIL("\"\\uD834\\", SPDK_JSON_PARSE_INCOMPLETE);
376d57bf4ccSDaniel Verkamp 	PARSE_FAIL("\"\\uD834\\u", SPDK_JSON_PARSE_INCOMPLETE);
377d57bf4ccSDaniel Verkamp 	PARSE_FAIL("\"\\uD834\\uD", SPDK_JSON_PARSE_INCOMPLETE);
378d57bf4ccSDaniel Verkamp 	PARSE_FAIL("\"\\uD834\\uDD1", SPDK_JSON_PARSE_INCOMPLETE);
379d57bf4ccSDaniel Verkamp 
380d57bf4ccSDaniel Verkamp 	/* High surrogate without low */
381d57bf4ccSDaniel Verkamp 	STR_FAIL("\\uD800", SPDK_JSON_PARSE_INVALID);
382d57bf4ccSDaniel Verkamp 	STR_FAIL("\\uD800abcdef", SPDK_JSON_PARSE_INVALID);
383ad51b333SDaniel Verkamp 
384ad51b333SDaniel Verkamp 	/* High surrogate followed by high surrogate */
385ad51b333SDaniel Verkamp 	STR_FAIL("\\uD800\\uD800", SPDK_JSON_PARSE_INVALID);
386d57bf4ccSDaniel Verkamp }
387d57bf4ccSDaniel Verkamp 
388d57bf4ccSDaniel Verkamp static void
test_parse_number(void)389d57bf4ccSDaniel Verkamp test_parse_number(void)
390d57bf4ccSDaniel Verkamp {
391d57bf4ccSDaniel Verkamp 	NUM_PASS("0");
392d57bf4ccSDaniel Verkamp 	NUM_PASS("1");
393d57bf4ccSDaniel Verkamp 	NUM_PASS("100");
394d57bf4ccSDaniel Verkamp 	NUM_PASS("-1");
395d57bf4ccSDaniel Verkamp 	NUM_PASS("-0");
396d57bf4ccSDaniel Verkamp 	NUM_PASS("3.0");
397d57bf4ccSDaniel Verkamp 	NUM_PASS("3.00");
398d57bf4ccSDaniel Verkamp 	NUM_PASS("3.001");
399d57bf4ccSDaniel Verkamp 	NUM_PASS("3.14159");
400d57bf4ccSDaniel Verkamp 	NUM_PASS("3.141592653589793238462643383279");
401d57bf4ccSDaniel Verkamp 	NUM_PASS("1e400");
402d57bf4ccSDaniel Verkamp 	NUM_PASS("1E400");
403d57bf4ccSDaniel Verkamp 	NUM_PASS("0e10");
404d57bf4ccSDaniel Verkamp 	NUM_PASS("0e0");
405d57bf4ccSDaniel Verkamp 	NUM_PASS("-0e0");
406d57bf4ccSDaniel Verkamp 	NUM_PASS("-0e+0");
407d57bf4ccSDaniel Verkamp 	NUM_PASS("-0e-0");
408d57bf4ccSDaniel Verkamp 	NUM_PASS("1e+400");
409d57bf4ccSDaniel Verkamp 	NUM_PASS("1e-400");
410d57bf4ccSDaniel Verkamp 	NUM_PASS("6.022e23");
411d57bf4ccSDaniel Verkamp 	NUM_PASS("-1.234e+56");
412d57bf4ccSDaniel Verkamp 	NUM_PASS("1.23e+56");
413d57bf4ccSDaniel Verkamp 	NUM_PASS("-1.23e-56");
414d57bf4ccSDaniel Verkamp 	NUM_PASS("1.23e-56");
415d57bf4ccSDaniel Verkamp 	NUM_PASS("1e04");
416d57bf4ccSDaniel Verkamp 
417d57bf4ccSDaniel Verkamp 	/* Trailing garbage */
418d57bf4ccSDaniel Verkamp 	PARSE_PASS("0A", 1, "A");
419d57bf4ccSDaniel Verkamp 	VAL_NUMBER("0");
420d57bf4ccSDaniel Verkamp 
421d57bf4ccSDaniel Verkamp 	PARSE_PASS("0,", 1, ",");
422d57bf4ccSDaniel Verkamp 	VAL_NUMBER("0");
423d57bf4ccSDaniel Verkamp 
424d57bf4ccSDaniel Verkamp 	PARSE_PASS("0true", 1, "true");
425d57bf4ccSDaniel Verkamp 	VAL_NUMBER("0");
426d57bf4ccSDaniel Verkamp 
427d57bf4ccSDaniel Verkamp 	PARSE_PASS("00", 1, "0");
428d57bf4ccSDaniel Verkamp 	VAL_NUMBER("0");
429d57bf4ccSDaniel Verkamp 	PARSE_FAIL("[00", SPDK_JSON_PARSE_INVALID);
430d57bf4ccSDaniel Verkamp 
431d57bf4ccSDaniel Verkamp 	PARSE_PASS("007", 1, "07");
432d57bf4ccSDaniel Verkamp 	VAL_NUMBER("0");
433d57bf4ccSDaniel Verkamp 	PARSE_FAIL("[007]", SPDK_JSON_PARSE_INVALID);
434d57bf4ccSDaniel Verkamp 
435d57bf4ccSDaniel Verkamp 	PARSE_PASS("345.678.1", 1, ".1");
436d57bf4ccSDaniel Verkamp 	VAL_NUMBER("345.678");
437d57bf4ccSDaniel Verkamp 	PARSE_FAIL("[345.678.1]", SPDK_JSON_PARSE_INVALID);
438d57bf4ccSDaniel Verkamp 
439d57bf4ccSDaniel Verkamp 	PARSE_PASS("3.2e-4+5", 1, "+5");
440d57bf4ccSDaniel Verkamp 	VAL_NUMBER("3.2e-4");
441d57bf4ccSDaniel Verkamp 	PARSE_FAIL("[3.2e-4+5]", SPDK_JSON_PARSE_INVALID);
442d57bf4ccSDaniel Verkamp 
443d57bf4ccSDaniel Verkamp 	PARSE_PASS("3.4.5", 1, ".5");
444d57bf4ccSDaniel Verkamp 	VAL_NUMBER("3.4");
445d57bf4ccSDaniel Verkamp 	PARSE_FAIL("[3.4.5]", SPDK_JSON_PARSE_INVALID);
446d57bf4ccSDaniel Verkamp 
447d57bf4ccSDaniel Verkamp 	NUM_FAIL("345.", SPDK_JSON_PARSE_INCOMPLETE);
448d57bf4ccSDaniel Verkamp 	NUM_FAIL("+1", SPDK_JSON_PARSE_INVALID);
449d57bf4ccSDaniel Verkamp 	NUM_FAIL("--1", SPDK_JSON_PARSE_INVALID);
450d57bf4ccSDaniel Verkamp 	NUM_FAIL("3.", SPDK_JSON_PARSE_INCOMPLETE);
451d57bf4ccSDaniel Verkamp 	NUM_FAIL("3.+4", SPDK_JSON_PARSE_INVALID);
452d57bf4ccSDaniel Verkamp 	NUM_FAIL("3.2e+-4", SPDK_JSON_PARSE_INVALID);
453d57bf4ccSDaniel Verkamp 	NUM_FAIL("3.2e-+4", SPDK_JSON_PARSE_INVALID);
454d57bf4ccSDaniel Verkamp 	NUM_FAIL("3e+", SPDK_JSON_PARSE_INCOMPLETE);
455d57bf4ccSDaniel Verkamp 	NUM_FAIL("3e-", SPDK_JSON_PARSE_INCOMPLETE);
456d57bf4ccSDaniel Verkamp 	NUM_FAIL("3.e4", SPDK_JSON_PARSE_INVALID);
457ad51b333SDaniel Verkamp 	NUM_FAIL("3.2eX", SPDK_JSON_PARSE_INVALID);
458d57bf4ccSDaniel Verkamp 	NUM_FAIL("-", SPDK_JSON_PARSE_INCOMPLETE);
459d57bf4ccSDaniel Verkamp 	NUM_FAIL("NaN", SPDK_JSON_PARSE_INVALID);
460d57bf4ccSDaniel Verkamp 	NUM_FAIL(".123", SPDK_JSON_PARSE_INVALID);
461d57bf4ccSDaniel Verkamp }
462d57bf4ccSDaniel Verkamp 
463d57bf4ccSDaniel Verkamp static void
test_parse_array(void)464d57bf4ccSDaniel Verkamp test_parse_array(void)
465d57bf4ccSDaniel Verkamp {
466ad51b333SDaniel Verkamp 	char buffer[SPDK_JSON_MAX_NESTING_DEPTH + 2] = {0};
467ad51b333SDaniel Verkamp 
468d57bf4ccSDaniel Verkamp 	PARSE_PASS("[]", 2, "");
469d57bf4ccSDaniel Verkamp 	VAL_ARRAY_BEGIN(0);
470d57bf4ccSDaniel Verkamp 	VAL_ARRAY_END();
471d57bf4ccSDaniel Verkamp 
472d57bf4ccSDaniel Verkamp 	PARSE_PASS("[true]", 3, "");
473d57bf4ccSDaniel Verkamp 	VAL_ARRAY_BEGIN(1);
474d57bf4ccSDaniel Verkamp 	VAL_TRUE();
475d57bf4ccSDaniel Verkamp 	VAL_ARRAY_END();
476d57bf4ccSDaniel Verkamp 
477d57bf4ccSDaniel Verkamp 	PARSE_PASS("[true, false]", 4, "");
478d57bf4ccSDaniel Verkamp 	VAL_ARRAY_BEGIN(2);
479d57bf4ccSDaniel Verkamp 	VAL_TRUE();
480d57bf4ccSDaniel Verkamp 	VAL_FALSE();
481d57bf4ccSDaniel Verkamp 	VAL_ARRAY_END();
482d57bf4ccSDaniel Verkamp 
483d57bf4ccSDaniel Verkamp 	PARSE_PASS("[\"hello\"]", 3, "");
484d57bf4ccSDaniel Verkamp 	VAL_ARRAY_BEGIN(1);
485d57bf4ccSDaniel Verkamp 	VAL_STRING("hello");
486d57bf4ccSDaniel Verkamp 	VAL_ARRAY_END();
487d57bf4ccSDaniel Verkamp 
488d57bf4ccSDaniel Verkamp 	PARSE_PASS("[[]]", 4, "");
489d57bf4ccSDaniel Verkamp 	VAL_ARRAY_BEGIN(2);
490d57bf4ccSDaniel Verkamp 	VAL_ARRAY_BEGIN(0);
491d57bf4ccSDaniel Verkamp 	VAL_ARRAY_END();
492d57bf4ccSDaniel Verkamp 	VAL_ARRAY_END();
493d57bf4ccSDaniel Verkamp 
494d57bf4ccSDaniel Verkamp 	PARSE_PASS("[\"hello\", \"world\"]", 4, "");
495d57bf4ccSDaniel Verkamp 	VAL_ARRAY_BEGIN(2);
496d57bf4ccSDaniel Verkamp 	VAL_STRING("hello");
497d57bf4ccSDaniel Verkamp 	VAL_STRING("world");
498d57bf4ccSDaniel Verkamp 	VAL_ARRAY_END();
499d57bf4ccSDaniel Verkamp 
500d57bf4ccSDaniel Verkamp 	PARSE_PASS("[],", 2, ",");
501d57bf4ccSDaniel Verkamp 	VAL_ARRAY_BEGIN(0);
502d57bf4ccSDaniel Verkamp 	VAL_ARRAY_END();
503d57bf4ccSDaniel Verkamp 
504d57bf4ccSDaniel Verkamp 	PARSE_FAIL("]", SPDK_JSON_PARSE_INVALID);
505d57bf4ccSDaniel Verkamp 	PARSE_FAIL("[", SPDK_JSON_PARSE_INCOMPLETE);
506d57bf4ccSDaniel Verkamp 	PARSE_FAIL("[true", SPDK_JSON_PARSE_INCOMPLETE);
507d57bf4ccSDaniel Verkamp 	PARSE_FAIL("[\"hello", SPDK_JSON_PARSE_INCOMPLETE);
508d57bf4ccSDaniel Verkamp 	PARSE_FAIL("[\"hello\"", SPDK_JSON_PARSE_INCOMPLETE);
509d57bf4ccSDaniel Verkamp 	PARSE_FAIL("[true,]", SPDK_JSON_PARSE_INVALID);
510d57bf4ccSDaniel Verkamp 	PARSE_FAIL("[,]", SPDK_JSON_PARSE_INVALID);
511d57bf4ccSDaniel Verkamp 	PARSE_FAIL("[,true]", SPDK_JSON_PARSE_INVALID);
512d57bf4ccSDaniel Verkamp 	PARSE_FAIL("[true}", SPDK_JSON_PARSE_INVALID);
513d57bf4ccSDaniel Verkamp 	PARSE_FAIL("[true,,true]", SPDK_JSON_PARSE_INVALID);
514ad51b333SDaniel Verkamp 
515ad51b333SDaniel Verkamp 	/* Nested arrays exactly up to the allowed nesting depth */
516ad51b333SDaniel Verkamp 	memset(buffer, '[', SPDK_JSON_MAX_NESTING_DEPTH);
517ad51b333SDaniel Verkamp 	buffer[SPDK_JSON_MAX_NESTING_DEPTH] = ' ';
518ad51b333SDaniel Verkamp 	PARSE_FAIL(buffer, SPDK_JSON_PARSE_INCOMPLETE);
519ad51b333SDaniel Verkamp 
520ad51b333SDaniel Verkamp 	/* Nested arrays exceeding the maximum allowed nesting depth for this implementation */
521ad51b333SDaniel Verkamp 	buffer[SPDK_JSON_MAX_NESTING_DEPTH] = '[';
522ad51b333SDaniel Verkamp 	PARSE_FAIL(buffer, SPDK_JSON_PARSE_MAX_DEPTH_EXCEEDED);
523d57bf4ccSDaniel Verkamp }
524d57bf4ccSDaniel Verkamp 
525d57bf4ccSDaniel Verkamp static void
test_parse_object(void)526d57bf4ccSDaniel Verkamp test_parse_object(void)
527d57bf4ccSDaniel Verkamp {
528d57bf4ccSDaniel Verkamp 	PARSE_PASS("{}", 2, "");
529d57bf4ccSDaniel Verkamp 	VAL_OBJECT_BEGIN(0);
530d57bf4ccSDaniel Verkamp 	VAL_OBJECT_END();
531d57bf4ccSDaniel Verkamp 
532d57bf4ccSDaniel Verkamp 	PARSE_PASS("{\"a\": true}", 4, "");
533d57bf4ccSDaniel Verkamp 	VAL_OBJECT_BEGIN(2);
534d57bf4ccSDaniel Verkamp 	VAL_NAME("a");
535d57bf4ccSDaniel Verkamp 	VAL_TRUE();
536d57bf4ccSDaniel Verkamp 	VAL_OBJECT_END();
537d57bf4ccSDaniel Verkamp 
538d57bf4ccSDaniel Verkamp 	PARSE_PASS("{\"abc\": \"def\"}", 4, "");
539d57bf4ccSDaniel Verkamp 	VAL_OBJECT_BEGIN(2);
540d57bf4ccSDaniel Verkamp 	VAL_NAME("abc");
541d57bf4ccSDaniel Verkamp 	VAL_STRING("def");
542d57bf4ccSDaniel Verkamp 	VAL_OBJECT_END();
543d57bf4ccSDaniel Verkamp 
544d57bf4ccSDaniel Verkamp 	PARSE_PASS("{\"a\": true, \"b\": false}", 6, "");
545d57bf4ccSDaniel Verkamp 	VAL_OBJECT_BEGIN(4);
546d57bf4ccSDaniel Verkamp 	VAL_NAME("a");
547d57bf4ccSDaniel Verkamp 	VAL_TRUE();
548d57bf4ccSDaniel Verkamp 	VAL_NAME("b");
549d57bf4ccSDaniel Verkamp 	VAL_FALSE();
550d57bf4ccSDaniel Verkamp 	VAL_OBJECT_END();
551d57bf4ccSDaniel Verkamp 
552d57bf4ccSDaniel Verkamp 	PARSE_PASS("{\"a\": { \"b\": true } }", 7, "");
553d57bf4ccSDaniel Verkamp 	VAL_OBJECT_BEGIN(5);
554d57bf4ccSDaniel Verkamp 	VAL_NAME("a");
555d57bf4ccSDaniel Verkamp 	VAL_OBJECT_BEGIN(2);
556d57bf4ccSDaniel Verkamp 	VAL_NAME("b");
557d57bf4ccSDaniel Verkamp 	VAL_TRUE();
558d57bf4ccSDaniel Verkamp 	VAL_OBJECT_END();
559d57bf4ccSDaniel Verkamp 	VAL_OBJECT_END();
560d57bf4ccSDaniel Verkamp 
561d57bf4ccSDaniel Verkamp 	PARSE_PASS("{\"{test\": 0}", 4, "");
562d57bf4ccSDaniel Verkamp 	VAL_OBJECT_BEGIN(2);
563d57bf4ccSDaniel Verkamp 	VAL_NAME("{test");
564d57bf4ccSDaniel Verkamp 	VAL_NUMBER("0");
565d57bf4ccSDaniel Verkamp 	VAL_OBJECT_END();
566d57bf4ccSDaniel Verkamp 
567d57bf4ccSDaniel Verkamp 	PARSE_PASS("{\"test}\": 1}", 4, "");
568d57bf4ccSDaniel Verkamp 	VAL_OBJECT_BEGIN(2);
569d57bf4ccSDaniel Verkamp 	VAL_NAME("test}");
570d57bf4ccSDaniel Verkamp 	VAL_NUMBER("1");
571d57bf4ccSDaniel Verkamp 	VAL_OBJECT_END();
572d57bf4ccSDaniel Verkamp 
573d57bf4ccSDaniel Verkamp 	PARSE_PASS("{\"\\\"\": 2}", 4, "");
574d57bf4ccSDaniel Verkamp 	VAL_OBJECT_BEGIN(2);
575d57bf4ccSDaniel Verkamp 	VAL_NAME("\"");
576d57bf4ccSDaniel Verkamp 	VAL_NUMBER("2");
577d57bf4ccSDaniel Verkamp 	VAL_OBJECT_END();
578d57bf4ccSDaniel Verkamp 
579d57bf4ccSDaniel Verkamp 	PARSE_PASS("{\"a\":true},", 4, ",");
580d57bf4ccSDaniel Verkamp 	VAL_OBJECT_BEGIN(2);
581d57bf4ccSDaniel Verkamp 	VAL_NAME("a");
582d57bf4ccSDaniel Verkamp 	VAL_TRUE();
583d57bf4ccSDaniel Verkamp 	VAL_OBJECT_END();
584d57bf4ccSDaniel Verkamp 
585d57bf4ccSDaniel Verkamp 	/* Object end without object begin (trailing garbage) */
586d57bf4ccSDaniel Verkamp 	PARSE_PASS("true}", 1, "}");
587d57bf4ccSDaniel Verkamp 	VAL_TRUE();
588d57bf4ccSDaniel Verkamp 
589d57bf4ccSDaniel Verkamp 	PARSE_PASS("0}", 1, "}");
590d57bf4ccSDaniel Verkamp 	VAL_NUMBER("0");
591d57bf4ccSDaniel Verkamp 
592d57bf4ccSDaniel Verkamp 	PARSE_PASS("\"a\"}", 1, "}");
593d57bf4ccSDaniel Verkamp 	VAL_STRING("a");
594d57bf4ccSDaniel Verkamp 
595d57bf4ccSDaniel Verkamp 	PARSE_FAIL("}", SPDK_JSON_PARSE_INVALID);
596d57bf4ccSDaniel Verkamp 	PARSE_FAIL("{", SPDK_JSON_PARSE_INCOMPLETE);
597d57bf4ccSDaniel Verkamp 	PARSE_FAIL("{\"a", SPDK_JSON_PARSE_INCOMPLETE);
598d57bf4ccSDaniel Verkamp 	PARSE_FAIL("{\"a\"", SPDK_JSON_PARSE_INCOMPLETE);
599d57bf4ccSDaniel Verkamp 	PARSE_FAIL("{\"a\":", SPDK_JSON_PARSE_INCOMPLETE);
600d57bf4ccSDaniel Verkamp 	PARSE_FAIL("{\"a\":true", SPDK_JSON_PARSE_INCOMPLETE);
601d57bf4ccSDaniel Verkamp 	PARSE_FAIL("{\"a\":true,", SPDK_JSON_PARSE_INCOMPLETE);
602ad51b333SDaniel Verkamp 	PARSE_FAIL("{\"a\":true]", SPDK_JSON_PARSE_INVALID);
603d57bf4ccSDaniel Verkamp 	PARSE_FAIL("{\"a\":true,}", SPDK_JSON_PARSE_INVALID);
604d57bf4ccSDaniel Verkamp 	PARSE_FAIL("{\"a\":true,\"}", SPDK_JSON_PARSE_INCOMPLETE);
605d57bf4ccSDaniel Verkamp 	PARSE_FAIL("{\"a\":true,\"b}", SPDK_JSON_PARSE_INCOMPLETE);
606d57bf4ccSDaniel Verkamp 	PARSE_FAIL("{\"a\":true,\"b\"}", SPDK_JSON_PARSE_INVALID);
607d57bf4ccSDaniel Verkamp 	PARSE_FAIL("{\"a\":true,\"b\":}", SPDK_JSON_PARSE_INVALID);
608d57bf4ccSDaniel Verkamp 	PARSE_FAIL("{\"a\":true,\"b\",}", SPDK_JSON_PARSE_INVALID);
609d57bf4ccSDaniel Verkamp 	PARSE_FAIL("{\"a\",}", SPDK_JSON_PARSE_INVALID);
610d57bf4ccSDaniel Verkamp 	PARSE_FAIL("{,\"a\": true}", SPDK_JSON_PARSE_INVALID);
611d57bf4ccSDaniel Verkamp 	PARSE_FAIL("{a:true}", SPDK_JSON_PARSE_INVALID);
612d57bf4ccSDaniel Verkamp 	PARSE_FAIL("{'a':true}", SPDK_JSON_PARSE_INVALID);
613d57bf4ccSDaniel Verkamp }
614d57bf4ccSDaniel Verkamp 
615d57bf4ccSDaniel Verkamp static void
test_parse_nesting(void)616d57bf4ccSDaniel Verkamp test_parse_nesting(void)
617d57bf4ccSDaniel Verkamp {
618d57bf4ccSDaniel Verkamp 	PARSE_PASS("[[[[[[[[]]]]]]]]", 16, "");
619d57bf4ccSDaniel Verkamp 
620d57bf4ccSDaniel Verkamp 	PARSE_PASS("{\"a\": [0, 1, 2]}", 8, "");
621d57bf4ccSDaniel Verkamp 	VAL_OBJECT_BEGIN(6);
622d57bf4ccSDaniel Verkamp 	VAL_NAME("a");
623d57bf4ccSDaniel Verkamp 	VAL_ARRAY_BEGIN(3);
624d57bf4ccSDaniel Verkamp 	VAL_NUMBER("0");
625d57bf4ccSDaniel Verkamp 	VAL_NUMBER("1");
626d57bf4ccSDaniel Verkamp 	VAL_NUMBER("2");
627d57bf4ccSDaniel Verkamp 	VAL_ARRAY_END();
628d57bf4ccSDaniel Verkamp 	VAL_OBJECT_END();
629d57bf4ccSDaniel Verkamp 
630d57bf4ccSDaniel Verkamp 	PARSE_PASS("{\"a\": [0, 1, 2], \"b\": 3 }", 10, "");
631d57bf4ccSDaniel Verkamp 	VAL_OBJECT_BEGIN(8);
632d57bf4ccSDaniel Verkamp 	VAL_NAME("a");
633d57bf4ccSDaniel Verkamp 	VAL_ARRAY_BEGIN(3);
634d57bf4ccSDaniel Verkamp 	VAL_NUMBER("0");
635d57bf4ccSDaniel Verkamp 	VAL_NUMBER("1");
636d57bf4ccSDaniel Verkamp 	VAL_NUMBER("2");
637d57bf4ccSDaniel Verkamp 	VAL_ARRAY_END();
638d57bf4ccSDaniel Verkamp 	VAL_NAME("b");
639d57bf4ccSDaniel Verkamp 	VAL_NUMBER("3");
640d57bf4ccSDaniel Verkamp 	VAL_OBJECT_END();
641d57bf4ccSDaniel Verkamp 
642d57bf4ccSDaniel Verkamp 	PARSE_PASS("[0, 1, {\"a\": 3}, 4, 5]", 10, "");
643d57bf4ccSDaniel Verkamp 	VAL_ARRAY_BEGIN(8);
644d57bf4ccSDaniel Verkamp 	VAL_NUMBER("0");
645d57bf4ccSDaniel Verkamp 	VAL_NUMBER("1");
646d57bf4ccSDaniel Verkamp 	VAL_OBJECT_BEGIN(2);
647d57bf4ccSDaniel Verkamp 	VAL_NAME("a");
648d57bf4ccSDaniel Verkamp 	VAL_NUMBER("3");
649d57bf4ccSDaniel Verkamp 	VAL_OBJECT_END();
650d57bf4ccSDaniel Verkamp 	VAL_NUMBER("4");
651d57bf4ccSDaniel Verkamp 	VAL_NUMBER("5");
652d57bf4ccSDaniel Verkamp 	VAL_ARRAY_END();
653d57bf4ccSDaniel Verkamp 
654d57bf4ccSDaniel Verkamp 	PARSE_PASS("\t[  { \"a\": {\"b\": [ {\"c\": 1}, 2 ],\n\"d\": 3}, \"e\" : 4}, 5 ] ", 20, "");
655d57bf4ccSDaniel Verkamp 	VAL_ARRAY_BEGIN(18);
656d57bf4ccSDaniel Verkamp 	VAL_OBJECT_BEGIN(15);
657d57bf4ccSDaniel Verkamp 	VAL_NAME("a");
658d57bf4ccSDaniel Verkamp 	VAL_OBJECT_BEGIN(10);
659d57bf4ccSDaniel Verkamp 	VAL_NAME("b");
660d57bf4ccSDaniel Verkamp 	VAL_ARRAY_BEGIN(5);
661d57bf4ccSDaniel Verkamp 	VAL_OBJECT_BEGIN(2);
662d57bf4ccSDaniel Verkamp 	VAL_NAME("c");
663d57bf4ccSDaniel Verkamp 	VAL_NUMBER("1");
664d57bf4ccSDaniel Verkamp 	VAL_OBJECT_END();
665d57bf4ccSDaniel Verkamp 	VAL_NUMBER("2");
666d57bf4ccSDaniel Verkamp 	VAL_ARRAY_END();
667d57bf4ccSDaniel Verkamp 	VAL_NAME("d");
668d57bf4ccSDaniel Verkamp 	VAL_NUMBER("3");
669d57bf4ccSDaniel Verkamp 	VAL_OBJECT_END();
670d57bf4ccSDaniel Verkamp 	VAL_NAME("e");
671d57bf4ccSDaniel Verkamp 	VAL_NUMBER("4");
672d57bf4ccSDaniel Verkamp 	VAL_OBJECT_END();
673d57bf4ccSDaniel Verkamp 	VAL_NUMBER("5");
674d57bf4ccSDaniel Verkamp 	VAL_ARRAY_END();
675d57bf4ccSDaniel Verkamp 
676d57bf4ccSDaniel Verkamp 	/* Examples from RFC 7159 */
677d57bf4ccSDaniel Verkamp 	PARSE_PASS(
678d57bf4ccSDaniel Verkamp 		"{\n"
679d57bf4ccSDaniel Verkamp 		"  \"Image\": {\n"
680d57bf4ccSDaniel Verkamp 		"    \"Width\":  800,\n"
681d57bf4ccSDaniel Verkamp 		"    \"Height\": 600,\n"
682d57bf4ccSDaniel Verkamp 		"    \"Title\":  \"View from 15th Floor\",\n"
683d57bf4ccSDaniel Verkamp 		"    \"Thumbnail\": {\n"
684d57bf4ccSDaniel Verkamp 		"        \"Url\":    \"http://www.example.com/image/481989943\",\n"
685d57bf4ccSDaniel Verkamp 		"        \"Height\": 125,\n"
686d57bf4ccSDaniel Verkamp 		"        \"Width\":  100\n"
687d57bf4ccSDaniel Verkamp 		"    },\n"
688d57bf4ccSDaniel Verkamp 		"    \"Animated\" : false,\n"
689d57bf4ccSDaniel Verkamp 		"    \"IDs\": [116, 943, 234, 38793]\n"
690d57bf4ccSDaniel Verkamp 		"  }\n"
691d57bf4ccSDaniel Verkamp 		"}\n",
692d57bf4ccSDaniel Verkamp 		29, "");
693d57bf4ccSDaniel Verkamp 
694d57bf4ccSDaniel Verkamp 	VAL_OBJECT_BEGIN(27);
695d57bf4ccSDaniel Verkamp 	VAL_NAME("Image");
696d57bf4ccSDaniel Verkamp 	VAL_OBJECT_BEGIN(24);
697d57bf4ccSDaniel Verkamp 	VAL_NAME("Width");
698d57bf4ccSDaniel Verkamp 	VAL_NUMBER("800");
699d57bf4ccSDaniel Verkamp 	VAL_NAME("Height");
700d57bf4ccSDaniel Verkamp 	VAL_NUMBER("600");
701d57bf4ccSDaniel Verkamp 	VAL_NAME("Title");
702d57bf4ccSDaniel Verkamp 	VAL_STRING("View from 15th Floor");
703d57bf4ccSDaniel Verkamp 	VAL_NAME("Thumbnail");
704d57bf4ccSDaniel Verkamp 	VAL_OBJECT_BEGIN(6);
705d57bf4ccSDaniel Verkamp 	VAL_NAME("Url");
706d57bf4ccSDaniel Verkamp 	VAL_STRING("http://www.example.com/image/481989943");
707d57bf4ccSDaniel Verkamp 	VAL_NAME("Height");
708d57bf4ccSDaniel Verkamp 	VAL_NUMBER("125");
709d57bf4ccSDaniel Verkamp 	VAL_NAME("Width");
710d57bf4ccSDaniel Verkamp 	VAL_NUMBER("100");
711d57bf4ccSDaniel Verkamp 	VAL_OBJECT_END();
712d57bf4ccSDaniel Verkamp 	VAL_NAME("Animated");
713d57bf4ccSDaniel Verkamp 	VAL_FALSE();
714d57bf4ccSDaniel Verkamp 	VAL_NAME("IDs");
715d57bf4ccSDaniel Verkamp 	VAL_ARRAY_BEGIN(4);
716d57bf4ccSDaniel Verkamp 	VAL_NUMBER("116");
717d57bf4ccSDaniel Verkamp 	VAL_NUMBER("943");
718d57bf4ccSDaniel Verkamp 	VAL_NUMBER("234");
719d57bf4ccSDaniel Verkamp 	VAL_NUMBER("38793");
720d57bf4ccSDaniel Verkamp 	VAL_ARRAY_END();
721d57bf4ccSDaniel Verkamp 	VAL_OBJECT_END();
722d57bf4ccSDaniel Verkamp 	VAL_OBJECT_END();
723d57bf4ccSDaniel Verkamp 
724d57bf4ccSDaniel Verkamp 	PARSE_PASS(
725d57bf4ccSDaniel Verkamp 		"[\n"
726d57bf4ccSDaniel Verkamp 		"  {\n"
727d57bf4ccSDaniel Verkamp 		"    \"precision\": \"zip\",\n"
728d57bf4ccSDaniel Verkamp 		"    \"Latitude\":  37.7668,\n"
729d57bf4ccSDaniel Verkamp 		"    \"Longitude\": -122.3959,\n"
730d57bf4ccSDaniel Verkamp 		"    \"Address\":   \"\",\n"
731d57bf4ccSDaniel Verkamp 		"    \"City\":      \"SAN FRANCISCO\",\n"
732d57bf4ccSDaniel Verkamp 		"    \"State\":     \"CA\",\n"
733d57bf4ccSDaniel Verkamp 		"    \"Zip\":       \"94107\",\n"
734d57bf4ccSDaniel Verkamp 		"    \"Country\":   \"US\"\n"
735d57bf4ccSDaniel Verkamp 		"  },\n"
736d57bf4ccSDaniel Verkamp 		"  {\n"
737d57bf4ccSDaniel Verkamp 		"    \"precision\": \"zip\",\n"
738d57bf4ccSDaniel Verkamp 		"    \"Latitude\":  37.371991,\n"
739d57bf4ccSDaniel Verkamp 		"    \"Longitude\": -122.026020,\n"
740d57bf4ccSDaniel Verkamp 		"    \"Address\":   \"\",\n"
741d57bf4ccSDaniel Verkamp 		"    \"City\":      \"SUNNYVALE\",\n"
742d57bf4ccSDaniel Verkamp 		"    \"State\":     \"CA\",\n"
743d57bf4ccSDaniel Verkamp 		"    \"Zip\":       \"94085\",\n"
744d57bf4ccSDaniel Verkamp 		"    \"Country\":   \"US\"\n"
745d57bf4ccSDaniel Verkamp 		"  }\n"
746d57bf4ccSDaniel Verkamp 		"]",
747d57bf4ccSDaniel Verkamp 		38, "");
748d57bf4ccSDaniel Verkamp 
749d57bf4ccSDaniel Verkamp 	VAL_ARRAY_BEGIN(36);
750d57bf4ccSDaniel Verkamp 	VAL_OBJECT_BEGIN(16);
751d57bf4ccSDaniel Verkamp 	VAL_NAME("precision");
752d57bf4ccSDaniel Verkamp 	VAL_STRING("zip");
753d57bf4ccSDaniel Verkamp 	VAL_NAME("Latitude");
754d57bf4ccSDaniel Verkamp 	VAL_NUMBER("37.7668");
755d57bf4ccSDaniel Verkamp 	VAL_NAME("Longitude");
756d57bf4ccSDaniel Verkamp 	VAL_NUMBER("-122.3959");
757d57bf4ccSDaniel Verkamp 	VAL_NAME("Address");
758d57bf4ccSDaniel Verkamp 	VAL_STRING("");
759d57bf4ccSDaniel Verkamp 	VAL_NAME("City");
760d57bf4ccSDaniel Verkamp 	VAL_STRING("SAN FRANCISCO");
761d57bf4ccSDaniel Verkamp 	VAL_NAME("State");
762d57bf4ccSDaniel Verkamp 	VAL_STRING("CA");
763d57bf4ccSDaniel Verkamp 	VAL_NAME("Zip");
764d57bf4ccSDaniel Verkamp 	VAL_STRING("94107");
765d57bf4ccSDaniel Verkamp 	VAL_NAME("Country");
766d57bf4ccSDaniel Verkamp 	VAL_STRING("US");
767d57bf4ccSDaniel Verkamp 	VAL_OBJECT_END();
768d57bf4ccSDaniel Verkamp 	VAL_OBJECT_BEGIN(16);
769d57bf4ccSDaniel Verkamp 	VAL_NAME("precision");
770d57bf4ccSDaniel Verkamp 	VAL_STRING("zip");
771d57bf4ccSDaniel Verkamp 	VAL_NAME("Latitude");
772d57bf4ccSDaniel Verkamp 	VAL_NUMBER("37.371991");
773d57bf4ccSDaniel Verkamp 	VAL_NAME("Longitude");
774d57bf4ccSDaniel Verkamp 	VAL_NUMBER("-122.026020");
775d57bf4ccSDaniel Verkamp 	VAL_NAME("Address");
776d57bf4ccSDaniel Verkamp 	VAL_STRING("");
777d57bf4ccSDaniel Verkamp 	VAL_NAME("City");
778d57bf4ccSDaniel Verkamp 	VAL_STRING("SUNNYVALE");
779d57bf4ccSDaniel Verkamp 	VAL_NAME("State");
780d57bf4ccSDaniel Verkamp 	VAL_STRING("CA");
781d57bf4ccSDaniel Verkamp 	VAL_NAME("Zip");
782d57bf4ccSDaniel Verkamp 	VAL_STRING("94085");
783d57bf4ccSDaniel Verkamp 	VAL_NAME("Country");
784d57bf4ccSDaniel Verkamp 	VAL_STRING("US");
785d57bf4ccSDaniel Verkamp 	VAL_OBJECT_END();
786d57bf4ccSDaniel Verkamp 	VAL_ARRAY_END();
787d57bf4ccSDaniel Verkamp 
788d57bf4ccSDaniel Verkamp 	/* Trailing garbage */
789d57bf4ccSDaniel Verkamp 	PARSE_PASS("{\"a\": [0, 1, 2]}]", 8, "]");
790d57bf4ccSDaniel Verkamp 	VAL_OBJECT_BEGIN(6);
791d57bf4ccSDaniel Verkamp 	VAL_NAME("a");
792d57bf4ccSDaniel Verkamp 	VAL_ARRAY_BEGIN(3);
793d57bf4ccSDaniel Verkamp 	VAL_NUMBER("0");
794d57bf4ccSDaniel Verkamp 	VAL_NUMBER("1");
795d57bf4ccSDaniel Verkamp 	VAL_NUMBER("2");
796d57bf4ccSDaniel Verkamp 	VAL_ARRAY_END();
797d57bf4ccSDaniel Verkamp 	VAL_OBJECT_END();
798d57bf4ccSDaniel Verkamp 
799d57bf4ccSDaniel Verkamp 	PARSE_PASS("{\"a\": [0, 1, 2]}}", 8, "}");
800d57bf4ccSDaniel Verkamp 	PARSE_PASS("{\"a\": [0, 1, 2]}]", 8, "]");
801d57bf4ccSDaniel Verkamp 	VAL_OBJECT_BEGIN(6);
802d57bf4ccSDaniel Verkamp 	VAL_NAME("a");
803d57bf4ccSDaniel Verkamp 	VAL_ARRAY_BEGIN(3);
804d57bf4ccSDaniel Verkamp 	VAL_NUMBER("0");
805d57bf4ccSDaniel Verkamp 	VAL_NUMBER("1");
806d57bf4ccSDaniel Verkamp 	VAL_NUMBER("2");
807d57bf4ccSDaniel Verkamp 	VAL_ARRAY_END();
808d57bf4ccSDaniel Verkamp 	VAL_OBJECT_END();
809d57bf4ccSDaniel Verkamp 
810d57bf4ccSDaniel Verkamp 	PARSE_FAIL("{\"a\": [0, 1, 2}]", SPDK_JSON_PARSE_INVALID);
811d57bf4ccSDaniel Verkamp 	PARSE_FAIL("{\"a\": [0, 1, 2]", SPDK_JSON_PARSE_INCOMPLETE);
812d57bf4ccSDaniel Verkamp }
813d57bf4ccSDaniel Verkamp 
814d57bf4ccSDaniel Verkamp 
815d57bf4ccSDaniel Verkamp static void
test_parse_comment(void)816d57bf4ccSDaniel Verkamp test_parse_comment(void)
817d57bf4ccSDaniel Verkamp {
818d57bf4ccSDaniel Verkamp 	/* Comments are not allowed by the JSON RFC */
819d57bf4ccSDaniel Verkamp 	PARSE_PASS("[0]", 3, "");
820d57bf4ccSDaniel Verkamp 	PARSE_FAIL("/* test */[0]", SPDK_JSON_PARSE_INVALID);
821d57bf4ccSDaniel Verkamp 	PARSE_FAIL("[/* test */0]", SPDK_JSON_PARSE_INVALID);
822d57bf4ccSDaniel Verkamp 	PARSE_FAIL("[0/* test */]", SPDK_JSON_PARSE_INVALID);
823d57bf4ccSDaniel Verkamp 
824d57bf4ccSDaniel Verkamp 	/*
825d57bf4ccSDaniel Verkamp 	 * This is allowed since the parser stops once it reads a complete JSON object.
826d57bf4ccSDaniel Verkamp 	 * The next parse call would fail (see tests above) when parsing the comment.
827d57bf4ccSDaniel Verkamp 	 */
828d57bf4ccSDaniel Verkamp 	PARSE_PASS("[0]/* test */", 3, "/* test */");
829d57bf4ccSDaniel Verkamp 
830d57bf4ccSDaniel Verkamp 	/*
831d57bf4ccSDaniel Verkamp 	 * Test with non-standard comments enabled.
832d57bf4ccSDaniel Verkamp 	 */
833d57bf4ccSDaniel Verkamp 	PARSE_PASS_FLAGS("/* test */[0]", 3, "", SPDK_JSON_PARSE_FLAG_ALLOW_COMMENTS);
834d57bf4ccSDaniel Verkamp 	VAL_ARRAY_BEGIN(1);
835d57bf4ccSDaniel Verkamp 	VAL_NUMBER("0");
836d57bf4ccSDaniel Verkamp 	VAL_ARRAY_END();
837d57bf4ccSDaniel Verkamp 
838d57bf4ccSDaniel Verkamp 	PARSE_PASS_FLAGS("[/* test */0]", 3, "", SPDK_JSON_PARSE_FLAG_ALLOW_COMMENTS);
839d57bf4ccSDaniel Verkamp 	VAL_ARRAY_BEGIN(1);
840d57bf4ccSDaniel Verkamp 	VAL_NUMBER("0");
841d57bf4ccSDaniel Verkamp 	VAL_ARRAY_END();
842d57bf4ccSDaniel Verkamp 
843d57bf4ccSDaniel Verkamp 	PARSE_PASS_FLAGS("[0/* test */]", 3, "", SPDK_JSON_PARSE_FLAG_ALLOW_COMMENTS);
844d57bf4ccSDaniel Verkamp 	VAL_ARRAY_BEGIN(1);
845d57bf4ccSDaniel Verkamp 	VAL_NUMBER("0");
846d57bf4ccSDaniel Verkamp 	VAL_ARRAY_END();
847d57bf4ccSDaniel Verkamp 
848d57bf4ccSDaniel Verkamp 	PARSE_FAIL_FLAGS("/* test */", SPDK_JSON_PARSE_INCOMPLETE, SPDK_JSON_PARSE_FLAG_ALLOW_COMMENTS);
849d57bf4ccSDaniel Verkamp 	PARSE_FAIL_FLAGS("[/* test */", SPDK_JSON_PARSE_INCOMPLETE, SPDK_JSON_PARSE_FLAG_ALLOW_COMMENTS);
850d57bf4ccSDaniel Verkamp 	PARSE_FAIL_FLAGS("[0/* test */", SPDK_JSON_PARSE_INCOMPLETE, SPDK_JSON_PARSE_FLAG_ALLOW_COMMENTS);
851d57bf4ccSDaniel Verkamp 
852d57bf4ccSDaniel Verkamp 	/*
853d57bf4ccSDaniel Verkamp 	 * Single-line comments
854d57bf4ccSDaniel Verkamp 	 */
855d57bf4ccSDaniel Verkamp 	PARSE_PASS_FLAGS("// test\n0", 1, "", SPDK_JSON_PARSE_FLAG_ALLOW_COMMENTS);
856d57bf4ccSDaniel Verkamp 	VAL_NUMBER("0");
857d57bf4ccSDaniel Verkamp 
858d57bf4ccSDaniel Verkamp 	PARSE_PASS_FLAGS("// test\r\n0", 1, "", SPDK_JSON_PARSE_FLAG_ALLOW_COMMENTS);
859d57bf4ccSDaniel Verkamp 	VAL_NUMBER("0");
860d57bf4ccSDaniel Verkamp 
861d57bf4ccSDaniel Verkamp 	PARSE_PASS_FLAGS("// [0] test\n0", 1, "", SPDK_JSON_PARSE_FLAG_ALLOW_COMMENTS);
862d57bf4ccSDaniel Verkamp 	VAL_NUMBER("0");
863d57bf4ccSDaniel Verkamp 
864d57bf4ccSDaniel Verkamp 	PARSE_FAIL_FLAGS("//", SPDK_JSON_PARSE_INCOMPLETE, SPDK_JSON_PARSE_FLAG_ALLOW_COMMENTS);
865d57bf4ccSDaniel Verkamp 	PARSE_FAIL_FLAGS("// test", SPDK_JSON_PARSE_INCOMPLETE, SPDK_JSON_PARSE_FLAG_ALLOW_COMMENTS);
866d57bf4ccSDaniel Verkamp 	PARSE_FAIL_FLAGS("//\n", SPDK_JSON_PARSE_INCOMPLETE, SPDK_JSON_PARSE_FLAG_ALLOW_COMMENTS);
867ad51b333SDaniel Verkamp 
868ad51b333SDaniel Verkamp 	/* Invalid character following slash */
869ad51b333SDaniel Verkamp 	PARSE_FAIL_FLAGS("[0/x", SPDK_JSON_PARSE_INVALID, SPDK_JSON_PARSE_FLAG_ALLOW_COMMENTS);
870ad51b333SDaniel Verkamp 
871ad51b333SDaniel Verkamp 	/* Single slash at end of buffer */
872ad51b333SDaniel Verkamp 	PARSE_FAIL_FLAGS("[0/", SPDK_JSON_PARSE_INCOMPLETE, SPDK_JSON_PARSE_FLAG_ALLOW_COMMENTS);
873d57bf4ccSDaniel Verkamp }
874d57bf4ccSDaniel Verkamp 
8758dd1cd21SBen Walker int
main(int argc,char ** argv)8768dd1cd21SBen Walker main(int argc, char **argv)
877d57bf4ccSDaniel Verkamp {
878d57bf4ccSDaniel Verkamp 	CU_pSuite	suite = NULL;
879d57bf4ccSDaniel Verkamp 	unsigned int	num_failures;
880d57bf4ccSDaniel Verkamp 
88178b696bcSVitaliy Mysak 	CU_initialize_registry();
882d57bf4ccSDaniel Verkamp 
883d57bf4ccSDaniel Verkamp 	suite = CU_add_suite("json", NULL, NULL);
884d57bf4ccSDaniel Verkamp 
885dcf0ca15SVitaliy Mysak 	CU_ADD_TEST(suite, test_parse_literal);
886dcf0ca15SVitaliy Mysak 	CU_ADD_TEST(suite, test_parse_string_simple);
887dcf0ca15SVitaliy Mysak 	CU_ADD_TEST(suite, test_parse_string_control_chars);
888dcf0ca15SVitaliy Mysak 	CU_ADD_TEST(suite, test_parse_string_utf8);
889dcf0ca15SVitaliy Mysak 	CU_ADD_TEST(suite, test_parse_string_escapes_twochar);
890dcf0ca15SVitaliy Mysak 	CU_ADD_TEST(suite, test_parse_string_escapes_unicode);
891dcf0ca15SVitaliy Mysak 	CU_ADD_TEST(suite, test_parse_number);
892dcf0ca15SVitaliy Mysak 	CU_ADD_TEST(suite, test_parse_array);
893dcf0ca15SVitaliy Mysak 	CU_ADD_TEST(suite, test_parse_object);
894dcf0ca15SVitaliy Mysak 	CU_ADD_TEST(suite, test_parse_nesting);
895dcf0ca15SVitaliy Mysak 	CU_ADD_TEST(suite, test_parse_comment);
896d57bf4ccSDaniel Verkamp 
897d57bf4ccSDaniel Verkamp 
898*ea941caeSKonrad Sztyber 	num_failures = spdk_ut_run_tests(argc, argv, NULL);
899d57bf4ccSDaniel Verkamp 
900d57bf4ccSDaniel Verkamp 	CU_cleanup_registry();
901d57bf4ccSDaniel Verkamp 
902d57bf4ccSDaniel Verkamp 	return num_failures;
903d57bf4ccSDaniel Verkamp }
904