]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved. | |
3 | * | |
4 | * Licensed under the Apache License 2.0 (the "License"). You may not use | |
5 | * this file except in compliance with the License. You can obtain a copy | |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
8 | */ | |
9 | ||
10 | #include <stdio.h> | |
11 | #include <string.h> | |
12 | ||
13 | #include "testutil.h" | |
14 | #include "internal/json_enc.h" | |
15 | ||
16 | struct helper { | |
17 | OSSL_JSON_ENC j; | |
18 | int init; | |
19 | uint32_t flags; | |
20 | BIO *mem_bio; | |
21 | }; | |
22 | ||
23 | static int helper_ensure(struct helper *h) | |
24 | { | |
25 | if (h->init) | |
26 | return 1; | |
27 | ||
28 | if (!TEST_ptr(h->mem_bio = BIO_new(BIO_s_mem()))) | |
29 | return 0; | |
30 | ||
31 | if (!ossl_json_init(&h->j, h->mem_bio, h->flags)) { | |
32 | BIO_free_all(h->mem_bio); | |
33 | h->mem_bio = NULL; | |
34 | return 0; | |
35 | } | |
36 | ||
37 | h->init = 1; | |
38 | return 1; | |
39 | } | |
40 | ||
41 | static void helper_cleanup(struct helper *h) | |
42 | { | |
43 | BIO_free_all(h->mem_bio); | |
44 | h->mem_bio = NULL; | |
45 | ||
46 | if (h->init) { | |
47 | ossl_json_cleanup(&h->j); | |
48 | h->init = 0; | |
49 | } | |
50 | } | |
51 | ||
52 | static void helper_set_flags(struct helper *h, uint32_t flags) | |
53 | { | |
54 | helper_cleanup(h); | |
55 | h->flags = flags; | |
56 | } | |
57 | ||
58 | struct script_word { | |
59 | void *p; | |
60 | uint64_t u64; | |
61 | int64_t i64; | |
62 | double d; | |
63 | void (*fp)(void); | |
64 | }; | |
65 | ||
66 | #define OP_P(x) { (x) }, | |
67 | #define OP_U64(x) { NULL, (x) }, | |
68 | #define OP_I64(x) { NULL, 0, (x) }, | |
69 | #define OP_D(x) { NULL, 0, 0, (x) }, | |
70 | #define OP_FP(x) { NULL, 0, 0, 0, (void (*)(void))(x) }, | |
71 | ||
72 | struct script_info { | |
73 | const char *name, *title; | |
74 | const struct script_word *words; | |
75 | size_t num_words; | |
76 | const char *expected_output; | |
77 | size_t expected_output_len; | |
78 | }; | |
79 | ||
80 | typedef const struct script_info *(*info_func)(void); | |
81 | ||
82 | enum { | |
83 | OPK_END, | |
84 | OPK_CALL, /* (OSSL_JSON_ENC *) */ | |
85 | OPK_CALL_P, /* (OSSL_JSON_ENC *, const void *) */ | |
86 | OPK_CALL_I, /* (OSSL_JSON_ENC *, int) */ | |
87 | OPK_CALL_U64, /* (OSSL_JSON_ENC *, uint64_t) */ | |
88 | OPK_CALL_I64, /* (OSSL_JSON_ENC *, int64_t) */ | |
89 | OPK_CALL_D, /* (OSSL_JSON_ENC *, double) */ | |
90 | OPK_CALL_PZ, /* (OSSL_JSON_ENC *, const void *, size_t) */ | |
91 | OPK_ASSERT_ERROR, /* (OSSL_JSON_ENC *, int expect_error) */ | |
92 | OPK_INIT_FLAGS /* (uint32_t flags) */ | |
93 | }; | |
94 | ||
95 | typedef void (*fp_type)(OSSL_JSON_ENC *); | |
96 | typedef void (*fp_p_type)(OSSL_JSON_ENC *, const void *); | |
97 | typedef void (*fp_i_type)(OSSL_JSON_ENC *, int); | |
98 | typedef void (*fp_u64_type)(OSSL_JSON_ENC *, uint64_t); | |
99 | typedef void (*fp_i64_type)(OSSL_JSON_ENC *, int64_t); | |
100 | typedef void (*fp_d_type)(OSSL_JSON_ENC *, double); | |
101 | typedef void (*fp_pz_type)(OSSL_JSON_ENC *, const void *, size_t); | |
102 | ||
103 | #define OP_END() OP_U64(OPK_END) | |
104 | #define OP_CALL(f) OP_U64(OPK_CALL) OP_FP(f) | |
105 | #define OP_CALL_P(f, x) OP_U64(OPK_CALL_P) OP_FP(f) OP_P (x) | |
106 | #define OP_CALL_I(f, x) OP_U64(OPK_CALL_I) OP_FP(f) OP_I64(x) | |
107 | #define OP_CALL_U64(f, x) OP_U64(OPK_CALL_U64) OP_FP(f) OP_U64(x) | |
108 | #define OP_CALL_I64(f, x) OP_U64(OPK_CALL_I64) OP_FP(f) OP_I64(x) | |
109 | #define OP_CALL_D(f, x) OP_U64(OPK_CALL_D) OP_FP(f) OP_D (x) | |
110 | #define OP_CALL_PZ(f, x, xl) OP_U64(OPK_CALL_PZ) OP_FP(f) OP_P (x) OP_U64(xl) | |
111 | #define OP_ASSERT_ERROR(err) OP_U64(OPK_ASSERT_ERROR) OP_U64(err) | |
112 | #define OP_INIT_FLAGS(flags) OP_U64(OPK_INIT_FLAGS) OP_U64(flags) | |
113 | ||
114 | #define OPJ_BEGIN_O() OP_CALL(ossl_json_object_begin) | |
115 | #define OPJ_END_O() OP_CALL(ossl_json_object_end) | |
116 | #define OPJ_BEGIN_A() OP_CALL(ossl_json_array_begin) | |
117 | #define OPJ_END_A() OP_CALL(ossl_json_array_end) | |
118 | #define OPJ_NULL() OP_CALL(ossl_json_null) | |
119 | #define OPJ_BOOL(x) OP_CALL_I(ossl_json_bool, (x)) | |
120 | #define OPJ_U64(x) OP_CALL_U64(ossl_json_u64, (x)) | |
121 | #define OPJ_I64(x) OP_CALL_I64(ossl_json_i64, (x)) | |
122 | #define OPJ_F64(x) OP_CALL_D(ossl_json_f64, (x)) | |
123 | #define OPJ_KEY(x) OP_CALL_P(ossl_json_key, (x)) | |
124 | #define OPJ_STR(x) OP_CALL_P(ossl_json_str, (x)) | |
125 | #define OPJ_STR_LEN(x, xl) OP_CALL_PZ(ossl_json_str_len, (x), (xl)) | |
126 | #define OPJ_STR_HEX(x, xl) OP_CALL_PZ(ossl_json_str_hex, (x), (xl)) | |
127 | ||
128 | #define BEGIN_SCRIPT(name, title, flags) \ | |
129 | static const struct script_info *get_script_##name(void) \ | |
130 | { \ | |
131 | static const char script_name[] = #name; \ | |
132 | static const char script_title[] = #title; \ | |
133 | \ | |
134 | static const struct script_word script_words[] = { \ | |
135 | OP_INIT_FLAGS(flags) | |
136 | ||
137 | #define END_SCRIPT_EXPECTING(s, slen) \ | |
138 | OP_END() \ | |
139 | }; \ | |
140 | static const struct script_info script_info = { \ | |
141 | script_name, script_title, script_words, OSSL_NELEM(script_words), \ | |
142 | (s), (slen) \ | |
143 | }; \ | |
144 | return &script_info; \ | |
145 | } | |
146 | ||
147 | #ifdef OPENSSL_SYS_VMS | |
148 | /* | |
149 | * The VMS C compiler recognises \u in strings, and emits a warning, which | |
150 | * stops the build. Because we think we know what we're doing, we change that | |
151 | * particular message to be merely informational. | |
152 | */ | |
153 | # pragma message informational UCNNOMAP | |
154 | #endif | |
155 | ||
156 | #define END_SCRIPT_EXPECTING_S(s) END_SCRIPT_EXPECTING(s, SIZE_MAX) | |
157 | #define END_SCRIPT_EXPECTING_Q(s) END_SCRIPT_EXPECTING(#s, sizeof(#s) - 1) | |
158 | ||
159 | #define SCRIPT(name) get_script_##name, | |
160 | ||
161 | BEGIN_SCRIPT(null, "serialize a single null", 0) | |
162 | OPJ_NULL() | |
163 | END_SCRIPT_EXPECTING_Q(null) | |
164 | ||
165 | BEGIN_SCRIPT(obj_empty, "serialize an empty object", 0) | |
166 | OPJ_BEGIN_O() | |
167 | OPJ_END_O() | |
168 | END_SCRIPT_EXPECTING_Q({}) | |
169 | ||
170 | BEGIN_SCRIPT(array_empty, "serialize an empty array", 0) | |
171 | OPJ_BEGIN_A() | |
172 | OPJ_END_A() | |
173 | END_SCRIPT_EXPECTING_Q([]) | |
174 | ||
175 | BEGIN_SCRIPT(bool_false, "serialize false", 0) | |
176 | OPJ_BOOL(0) | |
177 | END_SCRIPT_EXPECTING_Q(false) | |
178 | ||
179 | BEGIN_SCRIPT(bool_true, "serialize true", 0) | |
180 | OPJ_BOOL(1) | |
181 | END_SCRIPT_EXPECTING_Q(true) | |
182 | ||
183 | BEGIN_SCRIPT(u64_0, "serialize u64(0)", 0) | |
184 | OPJ_U64(0) | |
185 | END_SCRIPT_EXPECTING_Q(0) | |
186 | ||
187 | BEGIN_SCRIPT(u64_1, "serialize u64(1)", 0) | |
188 | OPJ_U64(1) | |
189 | END_SCRIPT_EXPECTING_Q(1) | |
190 | ||
191 | BEGIN_SCRIPT(u64_10, "serialize u64(10)", 0) | |
192 | OPJ_U64(10) | |
193 | END_SCRIPT_EXPECTING_Q(10) | |
194 | ||
195 | BEGIN_SCRIPT(u64_12345, "serialize u64(12345)", 0) | |
196 | OPJ_U64(12345) | |
197 | END_SCRIPT_EXPECTING_Q(12345) | |
198 | ||
199 | BEGIN_SCRIPT(u64_18446744073709551615, "serialize u64(18446744073709551615)", 0) | |
200 | OPJ_U64(18446744073709551615ULL) | |
201 | END_SCRIPT_EXPECTING_Q(18446744073709551615) | |
202 | ||
203 | BEGIN_SCRIPT(i64_0, "serialize i64(0)", 0) | |
204 | OPJ_I64(0) | |
205 | END_SCRIPT_EXPECTING_Q(0) | |
206 | ||
207 | BEGIN_SCRIPT(i64_1, "serialize i64(1)", 0) | |
208 | OPJ_I64(1) | |
209 | END_SCRIPT_EXPECTING_Q(1) | |
210 | ||
211 | BEGIN_SCRIPT(i64_2, "serialize i64(2)", 0) | |
212 | OPJ_I64(2) | |
213 | END_SCRIPT_EXPECTING_Q(2) | |
214 | ||
215 | BEGIN_SCRIPT(i64_10, "serialize i64(10)", 0) | |
216 | OPJ_I64(10) | |
217 | END_SCRIPT_EXPECTING_Q(10) | |
218 | ||
219 | BEGIN_SCRIPT(i64_12345, "serialize i64(12345)", 0) | |
220 | OPJ_I64(12345) | |
221 | END_SCRIPT_EXPECTING_Q(12345) | |
222 | ||
223 | BEGIN_SCRIPT(i64_9223372036854775807, "serialize i64(9223372036854775807)", 0) | |
224 | OPJ_I64(9223372036854775807LL) | |
225 | END_SCRIPT_EXPECTING_Q(9223372036854775807) | |
226 | ||
227 | BEGIN_SCRIPT(i64_m1, "serialize i64(-1)", 0) | |
228 | OPJ_I64(-1) | |
229 | END_SCRIPT_EXPECTING_Q(-1) | |
230 | ||
231 | BEGIN_SCRIPT(i64_m2, "serialize i64(-2)", 0) | |
232 | OPJ_I64(-2) | |
233 | END_SCRIPT_EXPECTING_Q(-2) | |
234 | ||
235 | BEGIN_SCRIPT(i64_m10, "serialize i64(-10)", 0) | |
236 | OPJ_I64(-10) | |
237 | END_SCRIPT_EXPECTING_Q(-10) | |
238 | ||
239 | BEGIN_SCRIPT(i64_m12345, "serialize i64(-12345)", 0) | |
240 | OPJ_I64(-12345) | |
241 | END_SCRIPT_EXPECTING_Q(-12345) | |
242 | ||
243 | BEGIN_SCRIPT(i64_m9223372036854775807, "serialize i64(-9223372036854775807)", 0) | |
244 | OPJ_I64(-9223372036854775807LL) | |
245 | END_SCRIPT_EXPECTING_Q(-9223372036854775807) | |
246 | ||
247 | BEGIN_SCRIPT(i64_m9223372036854775808, "serialize i64(-9223372036854775808)", 0) | |
248 | OPJ_I64(-9223372036854775807LL - 1LL) | |
249 | END_SCRIPT_EXPECTING_Q(-9223372036854775808) | |
250 | ||
251 | BEGIN_SCRIPT(str_empty, "serialize \"\"", 0) | |
252 | OPJ_STR("") | |
253 | END_SCRIPT_EXPECTING_Q("") | |
254 | ||
255 | BEGIN_SCRIPT(str_a, "serialize \"a\"", 0) | |
256 | OPJ_STR("a") | |
257 | END_SCRIPT_EXPECTING_Q("a") | |
258 | ||
259 | BEGIN_SCRIPT(str_abc, "serialize \"abc\"", 0) | |
260 | OPJ_STR("abc") | |
261 | END_SCRIPT_EXPECTING_Q("abc") | |
262 | ||
263 | BEGIN_SCRIPT(str_quote, "serialize with quote", 0) | |
264 | OPJ_STR("abc\"def") | |
265 | END_SCRIPT_EXPECTING_Q("abc\"def") | |
266 | ||
267 | BEGIN_SCRIPT(str_quote2, "serialize with quote", 0) | |
268 | OPJ_STR("abc\"\"def") | |
269 | END_SCRIPT_EXPECTING_Q("abc\"\"def") | |
270 | ||
271 | BEGIN_SCRIPT(str_escape, "serialize with various escapes", 0) | |
272 | OPJ_STR("abc\"\"de'f\r\n\t\b\f\\\x01\v\x7f\\") | |
273 | END_SCRIPT_EXPECTING_Q("abc\"\"de'f\r\n\t\b\f\\\u0001\u000b\u007f\\") | |
274 | ||
275 | BEGIN_SCRIPT(str_len, "length-signalled string", 0) | |
276 | OPJ_STR_LEN("abcdef", 6) | |
277 | END_SCRIPT_EXPECTING_Q("abcdef") | |
278 | ||
279 | BEGIN_SCRIPT(str_len0, "0-length-signalled string", 0) | |
280 | OPJ_STR_LEN("", 0) | |
281 | END_SCRIPT_EXPECTING_Q("") | |
282 | ||
283 | BEGIN_SCRIPT(str_len_nul, "string with NUL", 0) | |
284 | OPJ_STR_LEN("x\0y", 3) | |
285 | END_SCRIPT_EXPECTING_Q("x\u0000y") | |
286 | ||
287 | BEGIN_SCRIPT(hex_data0, "zero-length hex data", 0) | |
288 | OPJ_STR_HEX("", 0) | |
289 | END_SCRIPT_EXPECTING_Q("") | |
290 | ||
291 | BEGIN_SCRIPT(hex_data, "hex data", 0) | |
292 | OPJ_STR_HEX("\x00\x01\x5a\xfb\xff", 5) | |
293 | END_SCRIPT_EXPECTING_Q("00015afbff") | |
294 | ||
295 | BEGIN_SCRIPT(array_nest1, "serialize nested empty arrays", 0) | |
296 | OPJ_BEGIN_A() | |
297 | OPJ_BEGIN_A() | |
298 | OPJ_END_A() | |
299 | OPJ_END_A() | |
300 | END_SCRIPT_EXPECTING_Q([[]]) | |
301 | ||
302 | BEGIN_SCRIPT(array_nest2, "serialize nested empty arrays", 0) | |
303 | OPJ_BEGIN_A() | |
304 | OPJ_BEGIN_A() | |
305 | OPJ_BEGIN_A() | |
306 | OPJ_END_A() | |
307 | OPJ_END_A() | |
308 | OPJ_END_A() | |
309 | END_SCRIPT_EXPECTING_Q([[[]]]) | |
310 | ||
311 | BEGIN_SCRIPT(array_nest3, "serialize nested empty arrays", 0) | |
312 | OPJ_BEGIN_A() | |
313 | OPJ_BEGIN_A() | |
314 | OPJ_BEGIN_A() | |
315 | OPJ_END_A() | |
316 | OPJ_BEGIN_A() | |
317 | OPJ_END_A() | |
318 | OPJ_BEGIN_A() | |
319 | OPJ_END_A() | |
320 | OPJ_END_A() | |
321 | OPJ_BEGIN_A() | |
322 | OPJ_END_A() | |
323 | OPJ_END_A() | |
324 | END_SCRIPT_EXPECTING_S("[[[],[],[]],[]]") | |
325 | ||
326 | BEGIN_SCRIPT(array_nest4, "deep nested arrays", 0) | |
327 | OPJ_BEGIN_A() | |
328 | OPJ_BEGIN_A() | |
329 | OPJ_BEGIN_A() | |
330 | OPJ_BEGIN_A() | |
331 | OPJ_BEGIN_A() | |
332 | OPJ_BEGIN_A() | |
333 | OPJ_BEGIN_A() | |
334 | OPJ_BEGIN_A() | |
335 | OPJ_BEGIN_A() | |
336 | OPJ_BEGIN_A() | |
337 | OPJ_BEGIN_A() | |
338 | OPJ_BEGIN_A() | |
339 | OPJ_BEGIN_A() | |
340 | OPJ_BEGIN_A() | |
341 | OPJ_BEGIN_A() | |
342 | OPJ_BEGIN_A() | |
343 | OPJ_BEGIN_A() | |
344 | OPJ_BEGIN_A() | |
345 | OPJ_BEGIN_A() | |
346 | OPJ_BEGIN_A() | |
347 | OPJ_END_A() | |
348 | OPJ_END_A() | |
349 | OPJ_END_A() | |
350 | OPJ_END_A() | |
351 | OPJ_END_A() | |
352 | OPJ_END_A() | |
353 | OPJ_END_A() | |
354 | OPJ_END_A() | |
355 | OPJ_END_A() | |
356 | OPJ_END_A() | |
357 | OPJ_END_A() | |
358 | OPJ_END_A() | |
359 | OPJ_END_A() | |
360 | OPJ_END_A() | |
361 | OPJ_END_A() | |
362 | OPJ_END_A() | |
363 | OPJ_END_A() | |
364 | OPJ_END_A() | |
365 | OPJ_END_A() | |
366 | OPJ_NULL() | |
367 | OPJ_END_A() | |
368 | END_SCRIPT_EXPECTING_S("[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]],null]") | |
369 | ||
370 | BEGIN_SCRIPT(obj_nontrivial1, "serialize nontrivial object", 0) | |
371 | OPJ_BEGIN_O() | |
372 | OPJ_KEY("") | |
373 | OPJ_NULL() | |
374 | OPJ_END_O() | |
375 | END_SCRIPT_EXPECTING_S("{\"\":null}") | |
376 | ||
377 | BEGIN_SCRIPT(obj_nontrivial2, "serialize nontrivial object", 0) | |
378 | OPJ_BEGIN_O() | |
379 | OPJ_KEY("") | |
380 | OPJ_NULL() | |
381 | OPJ_KEY("x") | |
382 | OPJ_NULL() | |
383 | OPJ_END_O() | |
384 | END_SCRIPT_EXPECTING_S("{\"\":null,\"x\":null}") | |
385 | ||
386 | BEGIN_SCRIPT(obj_nest1, "serialize nested objects", 0) | |
387 | OPJ_BEGIN_O() | |
388 | OPJ_KEY("") | |
389 | OPJ_BEGIN_O() | |
390 | OPJ_KEY("x") | |
391 | OPJ_U64(42) | |
392 | OPJ_END_O() | |
393 | OPJ_KEY("x") | |
394 | OPJ_BEGIN_A() | |
395 | OPJ_U64(42) | |
396 | OPJ_U64(101) | |
397 | OPJ_END_A() | |
398 | OPJ_KEY("y") | |
399 | OPJ_NULL() | |
400 | OPJ_KEY("z") | |
401 | OPJ_BEGIN_O() | |
402 | OPJ_KEY("z0") | |
403 | OPJ_I64(-1) | |
404 | OPJ_KEY("z1") | |
405 | OPJ_I64(-2) | |
406 | OPJ_END_O() | |
407 | OPJ_END_O() | |
408 | END_SCRIPT_EXPECTING_S("{\"\":{\"x\":42},\"x\":[42,101],\"y\":null,\"z\":{\"z0\":-1,\"z1\":-2}}") | |
409 | ||
410 | BEGIN_SCRIPT(err_obj_no_key, "error test: object item without key", 0) | |
411 | OPJ_BEGIN_O() | |
412 | OP_ASSERT_ERROR(0) | |
413 | OPJ_NULL() | |
414 | OP_ASSERT_ERROR(1) | |
415 | OPJ_END_O() | |
416 | OP_ASSERT_ERROR(1) | |
417 | END_SCRIPT_EXPECTING_S("{") | |
418 | ||
419 | BEGIN_SCRIPT(err_obj_multi_key, "error test: object item with repeated key", 0) | |
420 | OPJ_BEGIN_O() | |
421 | OPJ_KEY("x") | |
422 | OP_ASSERT_ERROR(0) | |
423 | OPJ_KEY("y") | |
424 | OP_ASSERT_ERROR(1) | |
425 | OPJ_NULL() | |
426 | OP_ASSERT_ERROR(1) | |
427 | END_SCRIPT_EXPECTING_S("{\"x\":") | |
428 | ||
429 | BEGIN_SCRIPT(err_obj_no_value, "error test: object item with no value", 0) | |
430 | OPJ_BEGIN_O() | |
431 | OPJ_KEY("x") | |
432 | OP_ASSERT_ERROR(0) | |
433 | OPJ_END_O() | |
434 | OP_ASSERT_ERROR(1) | |
435 | END_SCRIPT_EXPECTING_S("{\"x\":") | |
436 | ||
437 | BEGIN_SCRIPT(err_utf8, "error test: only basic ASCII supported", 0) | |
438 | OPJ_STR("\x80") | |
439 | OP_ASSERT_ERROR(0) | |
440 | END_SCRIPT_EXPECTING_S("\"\\u0080\"") | |
441 | ||
442 | BEGIN_SCRIPT(utf8_2, "test: valid UTF-8 2byte supported", 0) | |
443 | OPJ_STR("low=\xc2\x80, high=\xdf\xbf") | |
444 | OP_ASSERT_ERROR(0) | |
445 | END_SCRIPT_EXPECTING_S("\"low=\xc2\x80, high=\xdf\xbf\"") | |
446 | ||
447 | BEGIN_SCRIPT(utf8_3, "test: valid UTF-8 3byte supported", 0) | |
448 | OPJ_STR("low=\xe0\xa0\x80, high=\xef\xbf\xbf") | |
449 | OP_ASSERT_ERROR(0) | |
450 | END_SCRIPT_EXPECTING_S("\"low=\xe0\xa0\x80, high=\xef\xbf\xbf\"") | |
451 | ||
452 | BEGIN_SCRIPT(utf8_4, "test: valid UTF-8 4byte supported", 0) | |
453 | OPJ_STR("low=\xf0\x90\xbf\xbf, high=\xf4\x8f\xbf\xbf") | |
454 | OP_ASSERT_ERROR(0) | |
455 | END_SCRIPT_EXPECTING_S("\"low=\xf0\x90\xbf\xbf, high=\xf4\x8f\xbf\xbf\"") | |
456 | ||
457 | BEGIN_SCRIPT(ijson_int, "I-JSON: large integer", OSSL_JSON_FLAG_IJSON) | |
458 | OPJ_BEGIN_A() | |
459 | OPJ_U64(1) | |
460 | OPJ_I64(-1) | |
461 | OPJ_U64(9007199254740991) | |
462 | OPJ_U64(9007199254740992) | |
463 | OPJ_I64(-9007199254740991) | |
464 | OPJ_I64(-9007199254740992) | |
465 | OPJ_END_A() | |
466 | END_SCRIPT_EXPECTING_S("[1,-1,9007199254740991,\"9007199254740992\",-9007199254740991,\"-9007199254740992\"]") | |
467 | ||
468 | BEGIN_SCRIPT(multi_item, "multiple top level items", 0) | |
469 | OPJ_NULL() | |
470 | OPJ_NULL() | |
471 | OPJ_BEGIN_A() | |
472 | OPJ_END_A() | |
473 | OPJ_BEGIN_A() | |
474 | OPJ_END_A() | |
475 | END_SCRIPT_EXPECTING_S("nullnull[][]") | |
476 | ||
477 | BEGIN_SCRIPT(seq, "JSON-SEQ", OSSL_JSON_FLAG_SEQ) | |
478 | OPJ_NULL() | |
479 | OPJ_NULL() | |
480 | OPJ_NULL() | |
481 | OPJ_BEGIN_O() | |
482 | OPJ_KEY("x") | |
483 | OPJ_U64(1) | |
484 | OPJ_KEY("y") | |
485 | OPJ_BEGIN_O() | |
486 | OPJ_END_O() | |
487 | OPJ_END_O() | |
488 | END_SCRIPT_EXPECTING_S("\x1Enull\n" "\x1Enull\n" "\x1Enull\n" "\x1E{\"x\":1,\"y\":{}}\n") | |
489 | ||
490 | static const info_func scripts[] = { | |
491 | SCRIPT(null) | |
492 | SCRIPT(obj_empty) | |
493 | SCRIPT(array_empty) | |
494 | SCRIPT(bool_false) | |
495 | SCRIPT(bool_true) | |
496 | SCRIPT(u64_0) | |
497 | SCRIPT(u64_1) | |
498 | SCRIPT(u64_10) | |
499 | SCRIPT(u64_12345) | |
500 | SCRIPT(u64_18446744073709551615) | |
501 | SCRIPT(i64_0) | |
502 | SCRIPT(i64_1) | |
503 | SCRIPT(i64_2) | |
504 | SCRIPT(i64_10) | |
505 | SCRIPT(i64_12345) | |
506 | SCRIPT(i64_9223372036854775807) | |
507 | SCRIPT(i64_m1) | |
508 | SCRIPT(i64_m2) | |
509 | SCRIPT(i64_m10) | |
510 | SCRIPT(i64_m12345) | |
511 | SCRIPT(i64_m9223372036854775807) | |
512 | SCRIPT(i64_m9223372036854775808) | |
513 | SCRIPT(str_empty) | |
514 | SCRIPT(str_a) | |
515 | SCRIPT(str_abc) | |
516 | SCRIPT(str_quote) | |
517 | SCRIPT(str_quote2) | |
518 | SCRIPT(str_escape) | |
519 | SCRIPT(str_len) | |
520 | SCRIPT(str_len0) | |
521 | SCRIPT(str_len_nul) | |
522 | SCRIPT(hex_data0) | |
523 | SCRIPT(hex_data) | |
524 | SCRIPT(array_nest1) | |
525 | SCRIPT(array_nest2) | |
526 | SCRIPT(array_nest3) | |
527 | SCRIPT(array_nest4) | |
528 | SCRIPT(obj_nontrivial1) | |
529 | SCRIPT(obj_nontrivial2) | |
530 | SCRIPT(obj_nest1) | |
531 | SCRIPT(err_obj_no_key) | |
532 | SCRIPT(err_obj_multi_key) | |
533 | SCRIPT(err_obj_no_value) | |
534 | SCRIPT(err_utf8) | |
535 | SCRIPT(utf8_2) | |
536 | SCRIPT(utf8_3) | |
537 | SCRIPT(utf8_4) | |
538 | SCRIPT(ijson_int) | |
539 | SCRIPT(multi_item) | |
540 | SCRIPT(seq) | |
541 | }; | |
542 | ||
543 | /* Test runner. */ | |
544 | static int run_script(const struct script_info *info) | |
545 | { | |
546 | int ok = 0, asserted = -1; | |
547 | const struct script_word *words = info->words; | |
548 | size_t wp = 0; | |
549 | struct script_word w; | |
550 | struct helper h = {0}; | |
551 | BUF_MEM *bufp = NULL; | |
552 | ||
553 | TEST_info("running script '%s' (%s)", info->name, info->title); | |
554 | ||
555 | #define GET_WORD() (w = words[wp++]) | |
556 | #define GET_U64() (GET_WORD().u64) | |
557 | #define GET_I64() (GET_WORD().i64) | |
558 | #define GET_FP() (GET_WORD().fp) | |
559 | #define GET_P() (GET_WORD().p) | |
560 | ||
561 | for (;;) | |
562 | switch (GET_U64()) { | |
563 | case OPK_END: | |
564 | goto stop; | |
565 | case OPK_INIT_FLAGS: | |
566 | helper_set_flags(&h, (uint32_t)GET_U64()); | |
567 | break; | |
568 | case OPK_CALL: | |
569 | { | |
570 | fp_type f = (fp_type)GET_FP(); | |
571 | ||
572 | if (!TEST_true(helper_ensure(&h))) | |
573 | goto err; | |
574 | ||
575 | f(&h.j); | |
576 | break; | |
577 | } | |
578 | case OPK_CALL_I: | |
579 | { | |
580 | fp_i_type f = (fp_i_type)GET_FP(); | |
581 | ||
582 | if (!TEST_true(helper_ensure(&h))) | |
583 | goto err; | |
584 | ||
585 | f(&h.j, (int)GET_I64()); | |
586 | break; | |
587 | } | |
588 | case OPK_CALL_U64: | |
589 | { | |
590 | fp_u64_type f = (fp_u64_type)GET_FP(); | |
591 | ||
592 | if (!TEST_true(helper_ensure(&h))) | |
593 | goto err; | |
594 | ||
595 | f(&h.j, GET_U64()); | |
596 | break; | |
597 | } | |
598 | case OPK_CALL_I64: | |
599 | { | |
600 | fp_i64_type f = (fp_i64_type)GET_FP(); | |
601 | ||
602 | if (!TEST_true(helper_ensure(&h))) | |
603 | goto err; | |
604 | ||
605 | f(&h.j, GET_I64()); | |
606 | break; | |
607 | } | |
608 | case OPK_CALL_P: | |
609 | { | |
610 | fp_p_type f = (fp_p_type)GET_FP(); | |
611 | ||
612 | if (!TEST_true(helper_ensure(&h))) | |
613 | goto err; | |
614 | ||
615 | f(&h.j, GET_P()); | |
616 | break; | |
617 | } | |
618 | case OPK_CALL_PZ: | |
619 | { | |
620 | fp_pz_type f = (fp_pz_type)GET_FP(); | |
621 | void *p; | |
622 | uint64_t u64; | |
623 | ||
624 | if (!TEST_true(helper_ensure(&h))) | |
625 | goto err; | |
626 | ||
627 | p = GET_P(); | |
628 | u64 = GET_U64(); | |
629 | f(&h.j, p, (size_t)u64); | |
630 | break; | |
631 | } | |
632 | case OPK_ASSERT_ERROR: | |
633 | { | |
634 | if (!TEST_true(helper_ensure(&h))) | |
635 | goto err; | |
636 | ||
637 | asserted = (int)GET_U64(); | |
638 | if (!TEST_int_eq(ossl_json_in_error(&h.j), asserted)) | |
639 | goto err; | |
640 | ||
641 | break; | |
642 | } | |
643 | #define OP_ASSERT_ERROR(err) OP_U64(OPK_ASSERT_ERROR) OP_U64(err) | |
644 | ||
645 | default: | |
646 | TEST_error("unknown opcode"); | |
647 | goto err; | |
648 | } | |
649 | stop: | |
650 | ||
651 | if (!TEST_true(helper_ensure(&h))) | |
652 | goto err; | |
653 | ||
654 | if (!TEST_true(ossl_json_flush(&h.j))) | |
655 | goto err; | |
656 | ||
657 | /* Implicit error check if not done explicitly. */ | |
658 | if (asserted < 0 && !TEST_false(ossl_json_in_error(&h.j))) | |
659 | goto err; | |
660 | ||
661 | if (!TEST_true(BIO_get_mem_ptr(h.mem_bio, &bufp))) | |
662 | goto err; | |
663 | ||
664 | if (!TEST_mem_eq(bufp->data, bufp->length, | |
665 | info->expected_output, | |
666 | info->expected_output_len == SIZE_MAX | |
667 | ? strlen(info->expected_output) | |
668 | : info->expected_output_len)) | |
669 | goto err; | |
670 | ||
671 | ok = 1; | |
672 | err: | |
673 | if (!ok) | |
674 | TEST_error("script '%s' failed", info->name); | |
675 | ||
676 | helper_cleanup(&h); | |
677 | return ok; | |
678 | } | |
679 | ||
680 | static int test_json_enc(void) | |
681 | { | |
682 | int ok = 1; | |
683 | size_t i; | |
684 | ||
685 | for (i = 0; i < OSSL_NELEM(scripts); ++i) | |
686 | if (!TEST_true(run_script(scripts[i]()))) | |
687 | ok = 0; | |
688 | ||
689 | return ok; | |
690 | } | |
691 | ||
692 | int setup_tests(void) | |
693 | { | |
694 | ADD_TEST(test_json_enc); | |
695 | return 1; | |
696 | } |