xref: /spdk/lib/json/json_util.c (revision 8a0a98d35e21f282088edf28b9e8da66ec390e3a)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (c) Intel Corporation.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include "spdk/json.h"
35 
36 #include "spdk_internal/utf.h"
37 
38 size_t
39 spdk_json_val_len(const struct spdk_json_val *val)
40 {
41 	if (val == NULL) {
42 		return 0;
43 	}
44 
45 	if (val->type == SPDK_JSON_VAL_ARRAY_BEGIN || val->type == SPDK_JSON_VAL_OBJECT_BEGIN) {
46 		return val->len + 2;
47 	}
48 
49 	return 1;
50 }
51 
52 bool
53 spdk_json_strequal(const struct spdk_json_val *val, const char *str)
54 {
55 	size_t len;
56 
57 	if (val->type != SPDK_JSON_VAL_STRING && val->type != SPDK_JSON_VAL_NAME) {
58 		return false;
59 	}
60 
61 	len = strlen(str);
62 	if (val->len != len) {
63 		return false;
64 	}
65 
66 	return memcmp(val->start, str, len) == 0;
67 }
68 
69 char *
70 spdk_json_strdup(const struct spdk_json_val *val)
71 {
72 	size_t len;
73 	char *s;
74 
75 	if (val->type != SPDK_JSON_VAL_STRING && val->type != SPDK_JSON_VAL_NAME) {
76 		return NULL;
77 	}
78 
79 	len = val->len;
80 
81 	if (memchr(val->start, '\0', len)) {
82 		/* String contains embedded NUL, so it is not a valid C string. */
83 		return NULL;
84 	}
85 
86 	s = malloc(len + 1);
87 	if (s == NULL) {
88 		return s;
89 	}
90 
91 	memcpy(s, val->start, len);
92 	s[len] = '\0';
93 
94 	return s;
95 }
96 
97 struct spdk_json_num {
98 	bool negative;
99 	uint64_t significand;
100 	int64_t exponent;
101 };
102 
103 static int
104 spdk_json_number_split(const struct spdk_json_val *val, struct spdk_json_num *num)
105 {
106 	const char *iter;
107 	size_t remaining;
108 	uint64_t *pval;
109 	uint64_t frac_digits = 0;
110 	uint64_t exponent_u64 = 0;
111 	bool exponent_negative = false;
112 	enum {
113 		NUM_STATE_INT,
114 		NUM_STATE_FRAC,
115 		NUM_STATE_EXP,
116 	} state;
117 
118 	memset(num, 0, sizeof(*num));
119 
120 	if (val->type != SPDK_JSON_VAL_NUMBER) {
121 		return -EINVAL;
122 	}
123 
124 	remaining = val->len;
125 	if (remaining == 0) {
126 		return -EINVAL;
127 	}
128 
129 	iter = val->start;
130 	if (*iter == '-') {
131 		num->negative = true;
132 		iter++;
133 		remaining--;
134 	}
135 
136 	state = NUM_STATE_INT;
137 	pval = &num->significand;
138 	while (remaining--) {
139 		char c = *iter++;
140 
141 		if (c == '.') {
142 			state = NUM_STATE_FRAC;
143 		} else if (c == 'e' || c == 'E') {
144 			state = NUM_STATE_EXP;
145 			pval = &exponent_u64;
146 		} else if (c == '-') {
147 			assert(state == NUM_STATE_EXP);
148 			exponent_negative = true;
149 		} else if (c == '+') {
150 			assert(state == NUM_STATE_EXP);
151 			/* exp_negative = false; */ /* already false by default */
152 		} else {
153 			uint64_t new_val;
154 
155 			assert(c >= '0' && c <= '9');
156 			new_val = *pval * 10 + c - '0';
157 			if (new_val < *pval) {
158 				return -ERANGE;
159 			}
160 
161 			if (state == NUM_STATE_FRAC) {
162 				frac_digits++;
163 			}
164 
165 			*pval = new_val;
166 		}
167 	}
168 
169 	if (exponent_negative) {
170 		if (exponent_u64 > 9223372036854775808ULL) { /* abs(INT64_MIN) */
171 			return -ERANGE;
172 		}
173 		num->exponent = (int64_t) - exponent_u64;
174 	} else {
175 		if (exponent_u64 > INT64_MAX) {
176 			return -ERANGE;
177 		}
178 		num->exponent = exponent_u64;
179 	}
180 	num->exponent -= frac_digits;
181 
182 	/* Apply as much of the exponent as possible without overflow or truncation */
183 	if (num->exponent < 0) {
184 		while (num->exponent && num->significand >= 10 && num->significand % 10 == 0) {
185 			num->significand /= 10;
186 			num->exponent++;
187 		}
188 	} else { /* positive exponent */
189 		while (num->exponent) {
190 			uint64_t new_val = num->significand * 10;
191 
192 			if (new_val < num->significand) {
193 				break;
194 			}
195 
196 			num->significand = new_val;
197 			num->exponent--;
198 		}
199 	}
200 
201 	return 0;
202 }
203 
204 int
205 spdk_json_number_to_uint16(const struct spdk_json_val *val, uint16_t *num)
206 {
207 	struct spdk_json_num split_num;
208 	int rc;
209 
210 	rc = spdk_json_number_split(val, &split_num);
211 	if (rc) {
212 		return rc;
213 	}
214 
215 	if (split_num.exponent || split_num.negative) {
216 		return -ERANGE;
217 	}
218 
219 	if (split_num.significand > UINT16_MAX) {
220 		return -ERANGE;
221 	}
222 	*num = (uint16_t)split_num.significand;
223 	return 0;
224 }
225 
226 int
227 spdk_json_number_to_int32(const struct spdk_json_val *val, int32_t *num)
228 {
229 	struct spdk_json_num split_num;
230 	int rc;
231 
232 	rc = spdk_json_number_split(val, &split_num);
233 	if (rc) {
234 		return rc;
235 	}
236 
237 	if (split_num.exponent) {
238 		return -ERANGE;
239 	}
240 
241 	if (split_num.negative) {
242 		if (split_num.significand > 2147483648) { /* abs(INT32_MIN) */
243 			return -ERANGE;
244 		}
245 		*num = (int32_t) - (int64_t)split_num.significand;
246 		return 0;
247 	}
248 
249 	/* positive */
250 	if (split_num.significand > INT32_MAX) {
251 		return -ERANGE;
252 	}
253 	*num = (int32_t)split_num.significand;
254 	return 0;
255 }
256 
257 int
258 spdk_json_number_to_uint32(const struct spdk_json_val *val, uint32_t *num)
259 {
260 	struct spdk_json_num split_num;
261 	int rc;
262 
263 	rc = spdk_json_number_split(val, &split_num);
264 	if (rc) {
265 		return rc;
266 	}
267 
268 	if (split_num.exponent || split_num.negative) {
269 		return -ERANGE;
270 	}
271 
272 	if (split_num.significand > UINT32_MAX) {
273 		return -ERANGE;
274 	}
275 	*num = (uint32_t)split_num.significand;
276 	return 0;
277 }
278 
279 int
280 spdk_json_number_to_uint64(const struct spdk_json_val *val, uint64_t *num)
281 {
282 	struct spdk_json_num split_num;
283 	int rc;
284 
285 	rc = spdk_json_number_split(val, &split_num);
286 	if (rc) {
287 		return rc;
288 	}
289 
290 	if (split_num.exponent || split_num.negative) {
291 		return -ERANGE;
292 	}
293 
294 	*num = split_num.significand;
295 	return 0;
296 }
297 
298 int
299 spdk_json_decode_object(const struct spdk_json_val *values,
300 			const struct spdk_json_object_decoder *decoders, size_t num_decoders, void *out)
301 {
302 	uint32_t i;
303 	bool invalid = false;
304 	size_t decidx;
305 	bool *seen;
306 
307 	if (values == NULL || values->type != SPDK_JSON_VAL_OBJECT_BEGIN) {
308 		return -1;
309 	}
310 
311 	seen = calloc(sizeof(bool), num_decoders);
312 	if (seen == NULL) {
313 		return -1;
314 	}
315 
316 	for (i = 0; i < values->len;) {
317 		const struct spdk_json_val *name = &values[i + 1];
318 		const struct spdk_json_val *v = &values[i + 2];
319 		bool found = false;
320 
321 		for (decidx = 0; decidx < num_decoders; decidx++) {
322 			const struct spdk_json_object_decoder *dec = &decoders[decidx];
323 			if (spdk_json_strequal(name, dec->name)) {
324 				void *field = (void *)((uintptr_t)out + dec->offset);
325 
326 				found = true;
327 
328 				if (seen[decidx]) {
329 					/* duplicate field name */
330 					invalid = true;
331 				} else {
332 					seen[decidx] = true;
333 					if (dec->decode_func(v, field)) {
334 						invalid = true;
335 						/* keep going to fill out any other valid keys */
336 					}
337 				}
338 				break;
339 			}
340 		}
341 
342 		if (!found) {
343 			invalid = true;
344 		}
345 
346 		i += 1 + spdk_json_val_len(v);
347 	}
348 
349 	for (decidx = 0; decidx < num_decoders; decidx++) {
350 		if (!decoders[decidx].optional && !seen[decidx]) {
351 			/* required field is missing */
352 			invalid = true;
353 			break;
354 		}
355 	}
356 
357 	free(seen);
358 	return invalid ? -1 : 0;
359 }
360 
361 int
362 spdk_json_decode_array(const struct spdk_json_val *values, spdk_json_decode_fn decode_func,
363 		       void *out, size_t max_size, size_t *out_size, size_t stride)
364 {
365 	uint32_t i;
366 	char *field;
367 	char *out_end;
368 
369 	if (values == NULL || values->type != SPDK_JSON_VAL_ARRAY_BEGIN) {
370 		return -1;
371 	}
372 
373 	*out_size = 0;
374 	field = out;
375 	out_end = field + max_size * stride;
376 	for (i = 0; i < values->len;) {
377 		const struct spdk_json_val *v = &values[i + 1];
378 
379 		if (field == out_end) {
380 			return -1;
381 		}
382 
383 		if (decode_func(v, field)) {
384 			return -1;
385 		}
386 
387 		i += spdk_json_val_len(v);
388 		field += stride;
389 		(*out_size)++;
390 	}
391 
392 	return 0;
393 }
394 
395 int
396 spdk_json_decode_bool(const struct spdk_json_val *val, void *out)
397 {
398 	bool *f = out;
399 
400 	if (val->type != SPDK_JSON_VAL_TRUE && val->type != SPDK_JSON_VAL_FALSE) {
401 		return -1;
402 	}
403 
404 	*f = val->type == SPDK_JSON_VAL_TRUE;
405 	return 0;
406 }
407 
408 int
409 spdk_json_decode_uint16(const struct spdk_json_val *val, void *out)
410 {
411 	uint16_t *i = out;
412 
413 	return spdk_json_number_to_uint16(val, i);
414 }
415 
416 int
417 spdk_json_decode_int32(const struct spdk_json_val *val, void *out)
418 {
419 	int32_t *i = out;
420 
421 	return spdk_json_number_to_int32(val, i);
422 }
423 
424 int
425 spdk_json_decode_uint32(const struct spdk_json_val *val, void *out)
426 {
427 	uint32_t *i = out;
428 
429 	return spdk_json_number_to_uint32(val, i);
430 }
431 
432 int
433 spdk_json_decode_uint64(const struct spdk_json_val *val, void *out)
434 {
435 	uint64_t *i = out;
436 
437 	return spdk_json_number_to_uint64(val, i);
438 }
439 
440 int
441 spdk_json_decode_string(const struct spdk_json_val *val, void *out)
442 {
443 	char **s = out;
444 
445 	free(*s);
446 
447 	*s = spdk_json_strdup(val);
448 
449 	if (*s) {
450 		return 0;
451 	} else {
452 		return -1;
453 	}
454 }
455