Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/util/support/t_json.c
34889 views
1
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
/* util/support/t_json.c - JSON test program */
3
/*
4
* Copyright (c) 2010 Kungliga Tekniska Högskolan
5
* (Royal Institute of Technology, Stockholm, Sweden).
6
* All rights reserved.
7
*
8
* Portions Copyright (c) 2010 Apple Inc. All rights reserved.
9
*
10
* Redistribution and use in source and binary forms, with or without
11
* modification, are permitted provided that the following conditions
12
* are met:
13
*
14
* 1. Redistributions of source code must retain the above copyright
15
* notice, this list of conditions and the following disclaimer.
16
*
17
* 2. Redistributions in binary form must reproduce the above copyright
18
* notice, this list of conditions and the following disclaimer in the
19
* documentation and/or other materials provided with the distribution.
20
*
21
* 3. Neither the name of the Institute nor the names of its contributors
22
* may be used to endorse or promote products derived from this software
23
* without specific prior written permission.
24
*
25
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
26
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
29
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35
* SUCH DAMAGE.
36
*/
37
/*
38
* Copyright (C) 2012 by the Massachusetts Institute of Technology.
39
* All rights reserved.
40
*
41
* Redistribution and use in source and binary forms, with or without
42
* modification, are permitted provided that the following conditions
43
* are met:
44
*
45
* * Redistributions of source code must retain the above copyright
46
* notice, this list of conditions and the following disclaimer.
47
*
48
* * Redistributions in binary form must reproduce the above copyright
49
* notice, this list of conditions and the following disclaimer in
50
* the documentation and/or other materials provided with the
51
* distribution.
52
*
53
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
54
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
55
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
56
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
57
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
58
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
59
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
60
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
61
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
62
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
63
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
64
* OF THE POSSIBILITY OF SUCH DAMAGE.
65
*/
66
67
#include <errno.h>
68
#include <stdio.h>
69
#include <stdlib.h>
70
#include <string.h>
71
72
#include <k5-json.h>
73
74
static void
75
err(const char *str)
76
{
77
fprintf(stderr, "%s\n", str);
78
exit(1);
79
}
80
81
static void
82
check(int pred, const char *str)
83
{
84
if (!pred)
85
err(str);
86
}
87
88
static void
89
test_array(void)
90
{
91
k5_json_string v1;
92
k5_json_number v2;
93
k5_json_null v3;
94
k5_json_array a;
95
k5_json_value v;
96
97
k5_json_array_create(&a);
98
k5_json_string_create("abc", &v1);
99
k5_json_array_add(a, v1);
100
k5_json_number_create(2, &v2);
101
k5_json_array_add(a, v2);
102
k5_json_null_create(&v3);
103
k5_json_array_add(a, v3);
104
105
check(k5_json_array_length(a) == 3, "array length");
106
v = k5_json_array_get(a, 2);
107
check(k5_json_get_tid(v) == K5_JSON_TID_NULL, "array[2] tid");
108
v = k5_json_array_get(a, 1);
109
check(k5_json_get_tid(v) == K5_JSON_TID_NUMBER, "array[1] tid");
110
check(k5_json_number_value(v) == 2, "array[1] value");
111
v = k5_json_array_get(a, 0);
112
check(k5_json_get_tid(v) == K5_JSON_TID_STRING, "array[0] tid");
113
check(strcmp(k5_json_string_utf8(v), "abc") == 0, "array[0] value");
114
115
k5_json_release(v1);
116
k5_json_release(v2);
117
k5_json_release(a);
118
119
k5_json_array_fmt(&a, "vnbiLssB", v3, 1, 9, (long long)-6, "def", NULL,
120
(void *)"ghij", (size_t)4);
121
v = k5_json_array_get(a, 0);
122
check(k5_json_get_tid(v) == K5_JSON_TID_NULL, "fmt array[0] tid");
123
v = k5_json_array_get(a, 1);
124
check(k5_json_get_tid(v) == K5_JSON_TID_NULL, "fmt array[1] tid");
125
v = k5_json_array_get(a, 2);
126
check(k5_json_get_tid(v) == K5_JSON_TID_BOOL, "fmt array[2] tid");
127
check(k5_json_bool_value(v), "fmt array[2] value");
128
v = k5_json_array_get(a, 3);
129
check(k5_json_get_tid(v) == K5_JSON_TID_NUMBER, "fmt array[3] tid");
130
check(k5_json_number_value(v) == 9, "fmt array[3] value");
131
v = k5_json_array_get(a, 4);
132
check(k5_json_get_tid(v) == K5_JSON_TID_NUMBER, "fmt array[4] tid");
133
check(k5_json_number_value(v) == -6, "fmt array[4] value");
134
v = k5_json_array_get(a, 5);
135
check(k5_json_get_tid(v) == K5_JSON_TID_STRING, "fmt array[5] tid");
136
check(strcmp(k5_json_string_utf8(v), "def") == 0, "fmt array[5] value");
137
v = k5_json_array_get(a, 6);
138
check(k5_json_get_tid(v) == K5_JSON_TID_NULL, "fmt array[6] tid");
139
v = k5_json_array_get(a, 7);
140
check(k5_json_get_tid(v) == K5_JSON_TID_STRING, "fmt array[7] tid");
141
check(strcmp(k5_json_string_utf8(v), "Z2hpag==") == 0,
142
"fmt array[7] value");
143
k5_json_release(v3);
144
k5_json_release(a);
145
}
146
147
static void
148
test_object(void)
149
{
150
k5_json_object object;
151
k5_json_number n, v1;
152
k5_json_string s, v2;
153
154
k5_json_object_create(&object);
155
k5_json_number_create(1, &v1);
156
k5_json_object_set(object, "key1", v1);
157
k5_json_string_create("hejsan", &v2);
158
k5_json_object_set(object, "key2", v2);
159
160
n = k5_json_object_get(object, "key1");
161
if (k5_json_number_value(n) != 1)
162
err("Retrieving key1 from object failed");
163
164
s = k5_json_object_get(object, "key2");
165
if (strcmp(k5_json_string_utf8(s), "hejsan") != 0)
166
err("Retrieving key2 from object failed");
167
168
check(k5_json_object_get(object, "key3") == NULL,
169
"object nonexistent key");
170
171
k5_json_object_set(object, "key1", NULL);
172
check(k5_json_object_get(object, "key1") == NULL,
173
"object removed key");
174
check(k5_json_object_get(object, "key2") != NULL,
175
"object remaining key");
176
177
k5_json_release(v1);
178
k5_json_release(v2);
179
k5_json_release(object);
180
}
181
182
static void
183
test_string(void)
184
{
185
k5_json_string s1, s2, s3;
186
unsigned char *data;
187
size_t len;
188
189
k5_json_string_create("hejsan", &s1);
190
k5_json_string_create("hejsan", &s2);
191
k5_json_string_create_base64("55555", 5, &s3);
192
193
if (strcmp(k5_json_string_utf8(s1), k5_json_string_utf8(s2)) != 0)
194
err("Identical strings are not identical");
195
if (strcmp(k5_json_string_utf8(s3), "NTU1NTU=") != 0)
196
err("base64 string has incorrect value");
197
k5_json_string_unbase64(s3, &data, &len);
198
if (len != 5 || memcmp(data, "55555", 5) != 0)
199
err("base64 string doesn't decode to correct value");
200
free(data);
201
202
k5_json_release(s1);
203
k5_json_release(s2);
204
k5_json_release(s3);
205
}
206
207
static void
208
test_json(void)
209
{
210
static char *tests[] = {
211
"{\"k1\":\"s1\",\"k2\":\"s2\"}",
212
"{\"k1\":[\"s1\",\"s2\",\"s3\"],\"k2\":\"s3\"}",
213
"{\"k1\":{\"k2\":\"s1\",\"k3\":\"s2\",\"k4\":\"s3\"},\"k5\":\"s4\"}",
214
"[\"v1\",\"v2\",[\"v3\",\"v4\",[\"v 5\",\" v 7 \"]],-123456789,"
215
"null,true,false,123456789,\"\"]",
216
"-1",
217
"\"\\\\abc\\\"\\nde\\b\\r/\\ff\\tghi\\u0001\\u001F\"",
218
"9223372036854775807",
219
"-9223372036854775808",
220
NULL
221
};
222
char **tptr, *s, *enc, *p, orig;
223
int i;
224
k5_json_value v, v2;
225
226
check(k5_json_decode("\"string\"", &v) == 0, "string1");
227
check(k5_json_get_tid(v) == K5_JSON_TID_STRING, "string1 tid");
228
check(strcmp(k5_json_string_utf8(v), "string") == 0, "string1 utf8");
229
k5_json_release(v);
230
231
check(k5_json_decode("\t \"foo\\\"bar\" ", &v) == 0, "string2");
232
check(k5_json_get_tid(v) == K5_JSON_TID_STRING, "string2 tid");
233
check(strcmp(k5_json_string_utf8(v), "foo\"bar") == 0, "string2 utf8");
234
k5_json_release(v);
235
236
check(k5_json_decode(" { \"key\" : \"value\" }", &v) == 0, "object1");
237
check(k5_json_get_tid(v) == K5_JSON_TID_OBJECT, "object1 tid");
238
v2 = k5_json_object_get(v, "key");
239
check(v2 != NULL, "object[key]");
240
check(k5_json_get_tid(v2) == K5_JSON_TID_STRING, "object1[key] tid");
241
check(strcmp(k5_json_string_utf8(v2), "value") == 0, "object1[key] utf8");
242
k5_json_release(v);
243
244
check(k5_json_decode("{ \"k1\" : { \"k2\" : \"s2\", \"k3\" : \"s3\" }, "
245
"\"k4\" : \"s4\" }", &v) == 0, "object2");
246
v2 = k5_json_object_get(v, "k1");
247
check(v2 != NULL, "object2[k1]");
248
check(k5_json_get_tid(v2) == K5_JSON_TID_OBJECT, "object2[k1] tid");
249
v2 = k5_json_object_get(v2, "k3");
250
check(v2 != NULL, "object2[k1][k3]");
251
check(k5_json_get_tid(v2) == K5_JSON_TID_STRING, "object2[k1][k3] tid");
252
check(strcmp(k5_json_string_utf8(v2), "s3") == 0, "object2[k1][k3] utf8");
253
k5_json_release(v);
254
255
check(k5_json_decode("{ \"k1\" : 1 }", &v) == 0, "object3");
256
check(k5_json_get_tid(v) == K5_JSON_TID_OBJECT, "object3 id");
257
v2 = k5_json_object_get(v, "k1");
258
check(k5_json_get_tid(v2) == K5_JSON_TID_NUMBER, "object3[k1] tid");
259
check(k5_json_number_value(v2) == 1, "object3[k1] value");
260
k5_json_release(v);
261
262
check(k5_json_decode("-10", &v) == 0, "number1");
263
check(k5_json_get_tid(v) == K5_JSON_TID_NUMBER, "number1 tid");
264
check(k5_json_number_value(v) == -10, "number1 value");
265
k5_json_release(v);
266
267
check(k5_json_decode("99", &v) == 0, "number2");
268
check(k5_json_get_tid(v) == K5_JSON_TID_NUMBER, "number2 tid");
269
check(k5_json_number_value(v) == 99, "number2 value");
270
k5_json_release(v);
271
272
check(k5_json_decode(" [ 1 ]", &v) == 0, "array1");
273
check(k5_json_get_tid(v) == K5_JSON_TID_ARRAY, "array1 tid");
274
check(k5_json_array_length(v) == 1, "array1 len");
275
v2 = k5_json_array_get(v, 0);
276
check(v2 != NULL, "array1[0]");
277
check(k5_json_get_tid(v2) == K5_JSON_TID_NUMBER, "array1[0] tid");
278
check(k5_json_number_value(v2) == 1, "array1[0] value");
279
k5_json_release(v);
280
281
check(k5_json_decode(" [ -1 ]", &v) == 0, "array2");
282
check(k5_json_get_tid(v) == K5_JSON_TID_ARRAY, "array2 tid");
283
check(k5_json_array_length(v) == 1, "array2 len");
284
v2 = k5_json_array_get(v, 0);
285
check(v2 != NULL, "array2[0]");
286
check(k5_json_get_tid(v2) == K5_JSON_TID_NUMBER, "array2[0] tid");
287
check(k5_json_number_value(v2) == -1, "array2[0] value");
288
k5_json_release(v);
289
290
check(k5_json_decode("18446744073709551616", &v) == EOVERFLOW,
291
"unsigned 64-bit overflow");
292
check(k5_json_decode("9223372036854775808", &v) == EOVERFLOW,
293
"signed 64-bit positive overflow");
294
check(k5_json_decode("-9223372036854775809", &v) == EOVERFLOW,
295
"signed 64-bit negative overflow");
296
297
for (tptr = tests; *tptr != NULL; tptr++) {
298
s = strdup(*tptr);
299
if (k5_json_decode(s, &v))
300
err(s);
301
if (k5_json_encode(v, &enc) || strcmp(enc, s) != 0)
302
err(s);
303
free(enc);
304
k5_json_release(v);
305
306
/* Fuzz bytes. Parsing may succeed or fail; we're just looking for
307
* memory access bugs. */
308
for (p = s; *p != '\0'; p++) {
309
orig = *p;
310
for (i = 0; i <= 255; i++) {
311
*p = i;
312
k5_json_decode(s, &v);
313
k5_json_release(v);
314
}
315
*p = orig;
316
}
317
free(s);
318
}
319
}
320
321
int
322
main(int argc, char **argv)
323
{
324
test_array();
325
test_object();
326
test_string();
327
test_json();
328
return 0;
329
}
330
331