1 /* SPDX-License-Identifier: LGPL-2.1+ */
5 #include "alloc-util.h"
8 #include "json-internal.h"
10 #include "string-util.h"
15 static void test_tokenizer(const char *data
, ...) {
16 unsigned line
= 0, column
= 0;
23 unsigned token_line
, token_column
;
24 _cleanup_free_
char *str
= NULL
;
25 JsonValue v
= JSON_VALUE_NULL
;
28 t
= json_tokenize(&data
, &str
, &v
, &token_line
, &token_column
, &state
, &line
, &column
);
33 if (t
== JSON_TOKEN_END
|| t
< 0)
36 else if (t
== JSON_TOKEN_STRING
) {
39 nn
= va_arg(ap
, const char *);
40 assert_se(streq_ptr(nn
, str
));
42 } else if (t
== JSON_TOKEN_REAL
) {
45 d
= va_arg(ap
, long double);
47 /* Valgrind doesn't support long double calculations and automatically downgrades to 80bit:
48 * http://www.valgrind.org/docs/manual/manual-core.html#manual-core.limits.
49 * Some architectures might not support long double either.
52 assert_se(fabsl(d
- v
.real
) < 1e-10 ||
53 fabsl((d
- v
.real
) / v
.real
) < 1e-10);
55 } else if (t
== JSON_TOKEN_INTEGER
) {
58 i
= va_arg(ap
, intmax_t);
59 assert_se(i
== v
.integer
);
61 } else if (t
== JSON_TOKEN_UNSIGNED
) {
64 u
= va_arg(ap
, uintmax_t);
65 assert_se(u
== v
.unsig
);
67 } else if (t
== JSON_TOKEN_BOOLEAN
) {
71 assert_se(b
== v
.boolean
);
78 typedef void (*Test
)(JsonVariant
*);
80 static void test_variant(const char *data
, Test test
) {
81 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
, *w
= NULL
;
82 _cleanup_free_
char *s
= NULL
;
85 r
= json_parse(data
, 0, &v
, NULL
, NULL
);
89 r
= json_variant_format(v
, 0, &s
);
92 assert_se((size_t) r
== strlen(s
));
94 log_info("formatted normally: %s\n", s
);
96 r
= json_parse(data
, JSON_PARSE_SENSITIVE
, &w
, NULL
, NULL
);
99 assert_se(json_variant_has_type(v
, json_variant_type(w
)));
100 assert_se(json_variant_has_type(w
, json_variant_type(v
)));
101 assert_se(json_variant_equal(v
, w
));
104 w
= json_variant_unref(w
);
106 r
= json_variant_format(v
, JSON_FORMAT_PRETTY
, &s
);
109 assert_se((size_t) r
== strlen(s
));
111 log_info("formatted prettily:\n%s", s
);
113 r
= json_parse(data
, 0, &w
, NULL
, NULL
);
117 assert_se(json_variant_has_type(v
, json_variant_type(w
)));
118 assert_se(json_variant_has_type(w
, json_variant_type(v
)));
119 assert_se(json_variant_equal(v
, w
));
122 r
= json_variant_format(v
, JSON_FORMAT_COLOR
, &s
);
125 assert_se((size_t) r
== strlen(s
));
126 printf("Normal with color: %s\n", s
);
129 r
= json_variant_format(v
, JSON_FORMAT_COLOR
|JSON_FORMAT_PRETTY
, &s
);
132 assert_se((size_t) r
== strlen(s
));
133 printf("Pretty with color:\n%s\n", s
);
139 static void test_1(JsonVariant
*v
) {
143 /* 3 keys + 3 values */
144 assert_se(json_variant_elements(v
) == 6);
147 p
= json_variant_by_key(v
, "k");
148 assert_se(p
&& json_variant_type(p
) == JSON_VARIANT_STRING
);
151 assert_se(streq(json_variant_string(p
), "v"));
154 p
= json_variant_by_key(v
, "foo");
155 assert_se(p
&& json_variant_type(p
) == JSON_VARIANT_ARRAY
&& json_variant_elements(p
) == 3);
157 /* check foo[0] = 1, foo[1] = 2, foo[2] = 3 */
158 for (i
= 0; i
< 3; ++i
) {
159 q
= json_variant_by_index(p
, i
);
160 assert_se(q
&& json_variant_type(q
) == JSON_VARIANT_UNSIGNED
&& json_variant_unsigned(q
) == (i
+1));
161 assert_se(q
&& json_variant_has_type(q
, JSON_VARIANT_INTEGER
) && json_variant_integer(q
) == (i
+1));
165 p
= json_variant_by_key(v
, "bar");
166 assert_se(p
&& json_variant_type(p
) == JSON_VARIANT_OBJECT
&& json_variant_elements(p
) == 2);
169 q
= json_variant_by_key(p
, "zap");
170 assert_se(q
&& json_variant_type(q
) == JSON_VARIANT_NULL
);
173 static void test_2(JsonVariant
*v
) {
176 /* 2 keys + 2 values */
177 assert_se(json_variant_elements(v
) == 4);
180 p
= json_variant_by_key(v
, "mutant");
181 assert_se(p
&& json_variant_type(p
) == JSON_VARIANT_ARRAY
&& json_variant_elements(p
) == 4);
184 q
= json_variant_by_index(p
, 0);
185 assert_se(q
&& json_variant_type(q
) == JSON_VARIANT_UNSIGNED
&& json_variant_unsigned(q
) == 1);
186 assert_se(q
&& json_variant_has_type(q
, JSON_VARIANT_INTEGER
) && json_variant_integer(q
) == 1);
188 /* mutant[1] == null */
189 q
= json_variant_by_index(p
, 1);
190 assert_se(q
&& json_variant_type(q
) == JSON_VARIANT_NULL
);
192 /* mutant[2] == "1" */
193 q
= json_variant_by_index(p
, 2);
194 assert_se(q
&& json_variant_type(q
) == JSON_VARIANT_STRING
&& streq(json_variant_string(q
), "1"));
196 /* mutant[3] == JSON_VARIANT_OBJECT */
197 q
= json_variant_by_index(p
, 3);
198 assert_se(q
&& json_variant_type(q
) == JSON_VARIANT_OBJECT
&& json_variant_elements(q
) == 2);
201 p
= json_variant_by_key(q
, "1");
202 assert_se(p
&& json_variant_type(p
) == JSON_VARIANT_ARRAY
&& json_variant_elements(p
) == 2);
205 q
= json_variant_by_index(p
, 0);
206 assert_se(q
&& json_variant_type(q
) == JSON_VARIANT_UNSIGNED
&& json_variant_unsigned(q
) == 1);
207 assert_se(q
&& json_variant_has_type(q
, JSON_VARIANT_INTEGER
) && json_variant_integer(q
) == 1);
210 q
= json_variant_by_index(p
, 1);
211 assert_se(q
&& json_variant_type(q
) == JSON_VARIANT_STRING
&& streq(json_variant_string(q
), "1"));
213 /* has thisisaverylongproperty */
214 p
= json_variant_by_key(v
, "thisisaverylongproperty");
215 assert_se(p
&& json_variant_type(p
) == JSON_VARIANT_REAL
&& fabsl(json_variant_real(p
) - 1.27) < 0.001);
218 static void test_zeroes(JsonVariant
*v
) {
221 /* Make sure zero is how we expect it. */
223 assert_se(json_variant_elements(v
) == 13);
225 for (i
= 0; i
< json_variant_elements(v
); i
++) {
229 assert_se(w
= json_variant_by_index(v
, i
));
231 assert_se(json_variant_integer(w
) == 0);
232 assert_se(json_variant_unsigned(w
) == 0U);
234 DISABLE_WARNING_FLOAT_EQUAL
;
235 assert_se(json_variant_real(w
) == 0.0L);
238 assert_se(json_variant_is_integer(w
));
239 assert_se(json_variant_is_unsigned(w
));
240 assert_se(json_variant_is_real(w
));
241 assert_se(json_variant_is_number(w
));
243 assert_se(!json_variant_is_negative(w
));
245 assert_se(IN_SET(json_variant_type(w
), JSON_VARIANT_INTEGER
, JSON_VARIANT_UNSIGNED
, JSON_VARIANT_REAL
));
247 for (j
= 0; j
< json_variant_elements(v
); j
++) {
250 assert_se(q
= json_variant_by_index(v
, j
));
252 assert_se(json_variant_equal(w
, q
));
257 static void test_build(void) {
258 _cleanup_(json_variant_unrefp
) JsonVariant
*a
= NULL
, *b
= NULL
;
259 _cleanup_free_
char *s
= NULL
, *t
= NULL
;
261 assert_se(json_build(&a
, JSON_BUILD_STRING("hallo")) >= 0);
262 assert_se(json_build(&b
, JSON_BUILD_LITERAL(" \"hallo\" ")) >= 0);
263 assert_se(json_variant_equal(a
, b
));
265 b
= json_variant_unref(b
);
267 assert_se(json_build(&b
, JSON_BUILD_VARIANT(a
)) >= 0);
268 assert_se(json_variant_equal(a
, b
));
270 b
= json_variant_unref(b
);
271 assert_se(json_build(&b
, JSON_BUILD_STRING("pief")) >= 0);
272 assert_se(!json_variant_equal(a
, b
));
274 a
= json_variant_unref(a
);
275 b
= json_variant_unref(b
);
277 assert_se(json_build(&a
, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("one", JSON_BUILD_INTEGER(7)),
278 JSON_BUILD_PAIR("two", JSON_BUILD_REAL(2.0)),
279 JSON_BUILD_PAIR("three", JSON_BUILD_INTEGER(0)))) >= 0);
281 assert_se(json_build(&b
, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("two", JSON_BUILD_INTEGER(2)),
282 JSON_BUILD_PAIR("three", JSON_BUILD_REAL(0)),
283 JSON_BUILD_PAIR("one", JSON_BUILD_REAL(7)))) >= 0);
285 assert_se(json_variant_equal(a
, b
));
287 a
= json_variant_unref(a
);
288 b
= json_variant_unref(b
);
290 const char* arr_1234
[] = {"one", "two", "three", "four", NULL
};
291 assert_se(json_build(&a
, JSON_BUILD_ARRAY(JSON_BUILD_OBJECT(JSON_BUILD_PAIR("x", JSON_BUILD_BOOLEAN(true)),
292 JSON_BUILD_PAIR("y", JSON_BUILD_OBJECT(JSON_BUILD_PAIR("this", JSON_BUILD_NULL
)))),
293 JSON_BUILD_VARIANT(NULL
),
294 JSON_BUILD_LITERAL(NULL
),
295 JSON_BUILD_STRING(NULL
),
297 JSON_BUILD_INTEGER(77),
298 JSON_BUILD_ARRAY(JSON_BUILD_VARIANT(JSON_VARIANT_STRING_CONST("foobar")),
299 JSON_BUILD_VARIANT(JSON_VARIANT_STRING_CONST("zzz"))),
300 JSON_BUILD_STRV((char**) arr_1234
))) >= 0);
302 assert_se(json_variant_format(a
, 0, &s
) >= 0);
303 log_info("GOT: %s\n", s
);
304 assert_se(json_parse(s
, 0, &b
, NULL
, NULL
) >= 0);
305 assert_se(json_variant_equal(a
, b
));
307 a
= json_variant_unref(a
);
308 b
= json_variant_unref(b
);
310 assert_se(json_build(&a
, JSON_BUILD_REAL(M_PIl
)) >= 0);
313 assert_se(json_variant_format(a
, 0, &s
) >= 0);
314 log_info("GOT: %s\n", s
);
315 assert_se(json_parse(s
, 0, &b
, NULL
, NULL
) >= 0);
316 assert_se(json_variant_format(b
, 0, &t
) >= 0);
317 log_info("GOT: %s\n", t
);
319 assert_se(streq(s
, t
));
321 a
= json_variant_unref(a
);
322 b
= json_variant_unref(b
);
324 assert_se(json_build(&a
, JSON_BUILD_OBJECT(
325 JSON_BUILD_PAIR("x", JSON_BUILD_STRING("y")),
326 JSON_BUILD_PAIR("z", JSON_BUILD_STRING("a")),
327 JSON_BUILD_PAIR("b", JSON_BUILD_STRING("c"))
330 assert_se(json_build(&b
, JSON_BUILD_OBJECT(
331 JSON_BUILD_PAIR("x", JSON_BUILD_STRING("y")),
332 JSON_BUILD_PAIR_CONDITION(false, "p", JSON_BUILD_STRING("q")),
333 JSON_BUILD_PAIR_CONDITION(true, "z", JSON_BUILD_STRING("a")),
334 JSON_BUILD_PAIR_CONDITION(false, "j", JSON_BUILD_ARRAY(JSON_BUILD_STRING("k"), JSON_BUILD_STRING("u"), JSON_BUILD_STRING("i"))),
335 JSON_BUILD_PAIR("b", JSON_BUILD_STRING("c"))
338 assert_se(json_variant_equal(a
, b
));
341 static void test_source(void) {
342 static const char data
[] =
346 "\"foo\" : \"bar\", \n"
347 "\"qüüx\" : [ 1, 2, 3,\n"
350 "\"miep\" : { \"hallo\" : 1 },\n"
358 _cleanup_fclose_
FILE *f
= NULL
;
359 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
361 printf("--- original begin ---\n"
363 "--- original end ---\n", data
);
365 assert_se(f
= fmemopen_unlocked((void*) data
, strlen(data
), "r"));
367 assert_se(json_parse_file(f
, "waldo", 0, &v
, NULL
, NULL
) >= 0);
369 printf("--- non-pretty begin ---\n");
370 json_variant_dump(v
, 0, stdout
, NULL
);
371 printf("\n--- non-pretty end ---\n");
373 printf("--- pretty begin ---\n");
374 json_variant_dump(v
, JSON_FORMAT_PRETTY
|JSON_FORMAT_COLOR
|JSON_FORMAT_SOURCE
, stdout
, NULL
);
375 printf("--- pretty end ---\n");
378 static void test_depth(void) {
379 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
383 v
= JSON_VARIANT_STRING_CONST("start");
385 /* Let's verify that the maximum depth checks work */
388 _cleanup_(json_variant_unrefp
) JsonVariant
*w
= NULL
;
390 assert_se(i
<= UINT16_MAX
);
392 r
= json_variant_new_array(&w
, &v
, 1);
394 r
= json_variant_new_object(&w
, (JsonVariant
*[]) { JSON_VARIANT_STRING_CONST("key"), v
}, 2);
396 log_info("max depth at %u", i
);
399 #if HAS_FEATURE_MEMORY_SANITIZER
400 /* msan doesn't like the stack nesting to be too deep. Let's quit early. */
402 log_info("quitting early at depth %u", i
);
409 json_variant_unref(v
);
413 json_variant_dump(v
, 0, stdout
, NULL
);
417 static void test_normalize(void) {
418 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
, *w
= NULL
;
419 _cleanup_free_
char *t
= NULL
;
421 assert_se(json_build(&v
, JSON_BUILD_OBJECT(
422 JSON_BUILD_PAIR("b", JSON_BUILD_STRING("x")),
423 JSON_BUILD_PAIR("c", JSON_BUILD_STRING("y")),
424 JSON_BUILD_PAIR("a", JSON_BUILD_STRING("z")))) >= 0);
426 assert_se(!json_variant_is_sorted(v
));
427 assert_se(!json_variant_is_normalized(v
));
429 assert_se(json_variant_format(v
, 0, &t
) >= 0);
430 assert_se(streq(t
, "{\"b\":\"x\",\"c\":\"y\",\"a\":\"z\"}"));
433 assert_se(json_build(&w
, JSON_BUILD_OBJECT(
434 JSON_BUILD_PAIR("bar", JSON_BUILD_STRING("zzz")),
435 JSON_BUILD_PAIR("foo", JSON_BUILD_VARIANT(v
)))) >= 0);
437 assert_se(json_variant_is_sorted(w
));
438 assert_se(!json_variant_is_normalized(w
));
440 assert_se(json_variant_format(w
, 0, &t
) >= 0);
441 assert_se(streq(t
, "{\"bar\":\"zzz\",\"foo\":{\"b\":\"x\",\"c\":\"y\",\"a\":\"z\"}}"));
444 assert_se(json_variant_sort(&v
) >= 0);
445 assert_se(json_variant_is_sorted(v
));
446 assert_se(json_variant_is_normalized(v
));
448 assert_se(json_variant_format(v
, 0, &t
) >= 0);
449 assert_se(streq(t
, "{\"a\":\"z\",\"b\":\"x\",\"c\":\"y\"}"));
452 assert_se(json_variant_normalize(&w
) >= 0);
453 assert_se(json_variant_is_sorted(w
));
454 assert_se(json_variant_is_normalized(w
));
456 assert_se(json_variant_format(w
, 0, &t
) >= 0);
457 assert_se(streq(t
, "{\"bar\":\"zzz\",\"foo\":{\"a\":\"z\",\"b\":\"x\",\"c\":\"y\"}}"));
461 static void test_bisect(void) {
462 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
465 /* Tests the bisection logic in json_variant_by_key() */
467 for (c
= 'z'; c
>= 'a'; c
--) {
472 _cleanup_(json_variant_unrefp
) JsonVariant
*w
= NULL
;
473 assert_se(json_variant_new_stringn(&w
, (char[4]) { '<', c
, c
, '>' }, 4) >= 0);
474 assert_se(json_variant_set_field(&v
, (char[2]) { c
, 0 }, w
) >= 0);
477 json_variant_dump(v
, JSON_FORMAT_COLOR
|JSON_FORMAT_PRETTY
, NULL
, NULL
);
479 assert_se(!json_variant_is_sorted(v
));
480 assert_se(!json_variant_is_normalized(v
));
481 assert_se(json_variant_normalize(&v
) >= 0);
482 assert_se(json_variant_is_sorted(v
));
483 assert_se(json_variant_is_normalized(v
));
485 json_variant_dump(v
, JSON_FORMAT_COLOR
|JSON_FORMAT_PRETTY
, NULL
, NULL
);
487 for (c
= 'a'; c
<= 'z'; c
++) {
491 k
= json_variant_by_key(v
, (char[2]) { c
, 0 });
492 assert_se(!k
== ((c
% 3) == 0));
497 assert_se(json_variant_is_string(k
));
499 z
= (char[5]){ '<', c
, c
, '>', 0};
500 assert_se(streq(json_variant_string(k
), z
));
504 int main(int argc
, char *argv
[]) {
505 test_setup_logging(LOG_DEBUG
);
507 test_tokenizer("x", -EINVAL
);
508 test_tokenizer("", JSON_TOKEN_END
);
509 test_tokenizer(" ", JSON_TOKEN_END
);
510 test_tokenizer("0", JSON_TOKEN_UNSIGNED
, (uintmax_t) 0, JSON_TOKEN_END
);
511 test_tokenizer("-0", JSON_TOKEN_INTEGER
, (intmax_t) 0, JSON_TOKEN_END
);
512 test_tokenizer("1234", JSON_TOKEN_UNSIGNED
, (uintmax_t) 1234, JSON_TOKEN_END
);
513 test_tokenizer("-1234", JSON_TOKEN_INTEGER
, (intmax_t) -1234, JSON_TOKEN_END
);
514 test_tokenizer("18446744073709551615", JSON_TOKEN_UNSIGNED
, (uintmax_t) UINT64_MAX
, JSON_TOKEN_END
);
515 test_tokenizer("-9223372036854775808", JSON_TOKEN_INTEGER
, (intmax_t) INT64_MIN
, JSON_TOKEN_END
);
516 test_tokenizer("18446744073709551616", JSON_TOKEN_REAL
, (long double) 18446744073709551616.0L, JSON_TOKEN_END
);
517 test_tokenizer("-9223372036854775809", JSON_TOKEN_REAL
, (long double) -9223372036854775809.0L, JSON_TOKEN_END
);
518 test_tokenizer("-1234", JSON_TOKEN_INTEGER
, (intmax_t) -1234, JSON_TOKEN_END
);
519 test_tokenizer("3.141", JSON_TOKEN_REAL
, (long double) 3.141, JSON_TOKEN_END
);
520 test_tokenizer("0.0", JSON_TOKEN_REAL
, (long double) 0.0, JSON_TOKEN_END
);
521 test_tokenizer("7e3", JSON_TOKEN_REAL
, (long double) 7e3
, JSON_TOKEN_END
);
522 test_tokenizer("-7e-3", JSON_TOKEN_REAL
, (long double) -7e-3, JSON_TOKEN_END
);
523 test_tokenizer("true", JSON_TOKEN_BOOLEAN
, true, JSON_TOKEN_END
);
524 test_tokenizer("false", JSON_TOKEN_BOOLEAN
, false, JSON_TOKEN_END
);
525 test_tokenizer("null", JSON_TOKEN_NULL
, JSON_TOKEN_END
);
526 test_tokenizer("{}", JSON_TOKEN_OBJECT_OPEN
, JSON_TOKEN_OBJECT_CLOSE
, JSON_TOKEN_END
);
527 test_tokenizer("\t {\n} \n", JSON_TOKEN_OBJECT_OPEN
, JSON_TOKEN_OBJECT_CLOSE
, JSON_TOKEN_END
);
528 test_tokenizer("[]", JSON_TOKEN_ARRAY_OPEN
, JSON_TOKEN_ARRAY_CLOSE
, JSON_TOKEN_END
);
529 test_tokenizer("\t [] \n\n", JSON_TOKEN_ARRAY_OPEN
, JSON_TOKEN_ARRAY_CLOSE
, JSON_TOKEN_END
);
530 test_tokenizer("\"\"", JSON_TOKEN_STRING
, "", JSON_TOKEN_END
);
531 test_tokenizer("\"foo\"", JSON_TOKEN_STRING
, "foo", JSON_TOKEN_END
);
532 test_tokenizer("\"foo\\nfoo\"", JSON_TOKEN_STRING
, "foo\nfoo", JSON_TOKEN_END
);
533 test_tokenizer("{\"foo\" : \"bar\"}", JSON_TOKEN_OBJECT_OPEN
, JSON_TOKEN_STRING
, "foo", JSON_TOKEN_COLON
, JSON_TOKEN_STRING
, "bar", JSON_TOKEN_OBJECT_CLOSE
, JSON_TOKEN_END
);
534 test_tokenizer("{\"foo\" : [true, false]}", JSON_TOKEN_OBJECT_OPEN
, JSON_TOKEN_STRING
, "foo", JSON_TOKEN_COLON
, JSON_TOKEN_ARRAY_OPEN
, JSON_TOKEN_BOOLEAN
, true, JSON_TOKEN_COMMA
, JSON_TOKEN_BOOLEAN
, false, JSON_TOKEN_ARRAY_CLOSE
, JSON_TOKEN_OBJECT_CLOSE
, JSON_TOKEN_END
);
535 test_tokenizer("\"\xef\xbf\xbd\"", JSON_TOKEN_STRING
, "\xef\xbf\xbd", JSON_TOKEN_END
);
536 test_tokenizer("\"\\ufffd\"", JSON_TOKEN_STRING
, "\xef\xbf\xbd", JSON_TOKEN_END
);
537 test_tokenizer("\"\\uf\"", -EINVAL
);
538 test_tokenizer("\"\\ud800a\"", -EINVAL
);
539 test_tokenizer("\"\\udc00\\udc00\"", -EINVAL
);
540 test_tokenizer("\"\\ud801\\udc37\"", JSON_TOKEN_STRING
, "\xf0\x90\x90\xb7", JSON_TOKEN_END
);
542 test_tokenizer("[1, 2, -3]", JSON_TOKEN_ARRAY_OPEN
, JSON_TOKEN_UNSIGNED
, (uintmax_t) 1, JSON_TOKEN_COMMA
, JSON_TOKEN_UNSIGNED
, (uintmax_t) 2, JSON_TOKEN_COMMA
, JSON_TOKEN_INTEGER
, (intmax_t) -3, JSON_TOKEN_ARRAY_CLOSE
, JSON_TOKEN_END
);
544 test_variant("{\"k\": \"v\", \"foo\": [1, 2, 3], \"bar\": {\"zap\": null}}", test_1
);
545 test_variant("{\"mutant\": [1, null, \"1\", {\"1\": [1, \"1\"]}], \"thisisaverylongproperty\": 1.27}", test_2
);
546 test_variant("{\"foo\" : \"\\u0935\\u093f\\u0935\\u0947\\u0915\\u0916\\u094d\\u092f\\u093e\\u0924\\u093f\\u0930\\u0935\\u093f\\u092a\\u094d\\u0932\\u0935\\u093e\\u0020\\u0939\\u093e\\u0928\\u094b\\u092a\\u093e\\u092f\\u0903\\u0964\"}", NULL
);
548 test_variant("[ 0, -0, 0.0, -0.0, 0.000, -0.000, 0e0, -0e0, 0e+0, -0e-0, 0e-0, -0e000, 0e+000 ]", test_zeroes
);