]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/lib/json/json_util.c
import 15.2.0 Octopus source
[ceph.git] / ceph / src / spdk / lib / json / json_util.c
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 #include "spdk_internal/log.h"
38
39 #define SPDK_JSON_DEBUG(...) SPDK_DEBUGLOG(SPDK_LOG_JSON_UTIL, __VA_ARGS__)
40
41 size_t
42 spdk_json_val_len(const struct spdk_json_val *val)
43 {
44 if (val == NULL) {
45 return 0;
46 }
47
48 if (val->type == SPDK_JSON_VAL_ARRAY_BEGIN || val->type == SPDK_JSON_VAL_OBJECT_BEGIN) {
49 return val->len + 2;
50 }
51
52 return 1;
53 }
54
55 bool
56 spdk_json_strequal(const struct spdk_json_val *val, const char *str)
57 {
58 size_t len;
59
60 if (val->type != SPDK_JSON_VAL_STRING && val->type != SPDK_JSON_VAL_NAME) {
61 return false;
62 }
63
64 len = strlen(str);
65 if (val->len != len) {
66 return false;
67 }
68
69 return memcmp(val->start, str, len) == 0;
70 }
71
72 char *
73 spdk_json_strdup(const struct spdk_json_val *val)
74 {
75 size_t len;
76 char *s;
77
78 if (val->type != SPDK_JSON_VAL_STRING && val->type != SPDK_JSON_VAL_NAME) {
79 return NULL;
80 }
81
82 len = val->len;
83
84 if (memchr(val->start, '\0', len)) {
85 /* String contains embedded NUL, so it is not a valid C string. */
86 return NULL;
87 }
88
89 s = malloc(len + 1);
90 if (s == NULL) {
91 return s;
92 }
93
94 memcpy(s, val->start, len);
95 s[len] = '\0';
96
97 return s;
98 }
99
100 struct spdk_json_num {
101 bool negative;
102 uint64_t significand;
103 int64_t exponent;
104 };
105
106 static int
107 spdk_json_number_split(const struct spdk_json_val *val, struct spdk_json_num *num)
108 {
109 const char *iter;
110 size_t remaining;
111 uint64_t *pval;
112 uint64_t frac_digits = 0;
113 uint64_t exponent_u64 = 0;
114 bool exponent_negative = false;
115 enum {
116 NUM_STATE_INT,
117 NUM_STATE_FRAC,
118 NUM_STATE_EXP,
119 } state;
120
121 memset(num, 0, sizeof(*num));
122
123 if (val->type != SPDK_JSON_VAL_NUMBER) {
124 return -EINVAL;
125 }
126
127 remaining = val->len;
128 if (remaining == 0) {
129 return -EINVAL;
130 }
131
132 iter = val->start;
133 if (*iter == '-') {
134 num->negative = true;
135 iter++;
136 remaining--;
137 }
138
139 state = NUM_STATE_INT;
140 pval = &num->significand;
141 while (remaining--) {
142 char c = *iter++;
143
144 if (c == '.') {
145 state = NUM_STATE_FRAC;
146 } else if (c == 'e' || c == 'E') {
147 state = NUM_STATE_EXP;
148 pval = &exponent_u64;
149 } else if (c == '-') {
150 assert(state == NUM_STATE_EXP);
151 exponent_negative = true;
152 } else if (c == '+') {
153 assert(state == NUM_STATE_EXP);
154 /* exp_negative = false; */ /* already false by default */
155 } else {
156 uint64_t new_val;
157
158 assert(c >= '0' && c <= '9');
159 new_val = *pval * 10 + c - '0';
160 if (new_val < *pval) {
161 return -ERANGE;
162 }
163
164 if (state == NUM_STATE_FRAC) {
165 frac_digits++;
166 }
167
168 *pval = new_val;
169 }
170 }
171
172 if (exponent_negative) {
173 if (exponent_u64 > 9223372036854775808ULL) { /* abs(INT64_MIN) */
174 return -ERANGE;
175 }
176 num->exponent = (int64_t) - exponent_u64;
177 } else {
178 if (exponent_u64 > INT64_MAX) {
179 return -ERANGE;
180 }
181 num->exponent = exponent_u64;
182 }
183 num->exponent -= frac_digits;
184
185 /* Apply as much of the exponent as possible without overflow or truncation */
186 if (num->exponent < 0) {
187 while (num->exponent && num->significand >= 10 && num->significand % 10 == 0) {
188 num->significand /= 10;
189 num->exponent++;
190 }
191 } else { /* positive exponent */
192 while (num->exponent) {
193 uint64_t new_val = num->significand * 10;
194
195 if (new_val < num->significand) {
196 break;
197 }
198
199 num->significand = new_val;
200 num->exponent--;
201 }
202 }
203
204 return 0;
205 }
206
207 int
208 spdk_json_number_to_uint16(const struct spdk_json_val *val, uint16_t *num)
209 {
210 struct spdk_json_num split_num;
211 int rc;
212
213 rc = spdk_json_number_split(val, &split_num);
214 if (rc) {
215 return rc;
216 }
217
218 if (split_num.exponent || split_num.negative) {
219 return -ERANGE;
220 }
221
222 if (split_num.significand > UINT16_MAX) {
223 return -ERANGE;
224 }
225 *num = (uint16_t)split_num.significand;
226 return 0;
227 }
228
229 int
230 spdk_json_number_to_int32(const struct spdk_json_val *val, int32_t *num)
231 {
232 struct spdk_json_num split_num;
233 int rc;
234
235 rc = spdk_json_number_split(val, &split_num);
236 if (rc) {
237 return rc;
238 }
239
240 if (split_num.exponent) {
241 return -ERANGE;
242 }
243
244 if (split_num.negative) {
245 if (split_num.significand > 2147483648) { /* abs(INT32_MIN) */
246 return -ERANGE;
247 }
248 *num = (int32_t) - (int64_t)split_num.significand;
249 return 0;
250 }
251
252 /* positive */
253 if (split_num.significand > INT32_MAX) {
254 return -ERANGE;
255 }
256 *num = (int32_t)split_num.significand;
257 return 0;
258 }
259
260 int
261 spdk_json_number_to_uint32(const struct spdk_json_val *val, uint32_t *num)
262 {
263 struct spdk_json_num split_num;
264 int rc;
265
266 rc = spdk_json_number_split(val, &split_num);
267 if (rc) {
268 return rc;
269 }
270
271 if (split_num.exponent || split_num.negative) {
272 return -ERANGE;
273 }
274
275 if (split_num.significand > UINT32_MAX) {
276 return -ERANGE;
277 }
278 *num = (uint32_t)split_num.significand;
279 return 0;
280 }
281
282 int
283 spdk_json_number_to_uint64(const struct spdk_json_val *val, uint64_t *num)
284 {
285 struct spdk_json_num split_num;
286 int rc;
287
288 rc = spdk_json_number_split(val, &split_num);
289 if (rc) {
290 return rc;
291 }
292
293 if (split_num.exponent || split_num.negative) {
294 return -ERANGE;
295 }
296
297 *num = split_num.significand;
298 return 0;
299 }
300
301 int
302 spdk_json_decode_object(const struct spdk_json_val *values,
303 const struct spdk_json_object_decoder *decoders, size_t num_decoders, void *out)
304 {
305 uint32_t i;
306 bool invalid = false;
307 size_t decidx;
308 bool *seen;
309
310 if (values == NULL || values->type != SPDK_JSON_VAL_OBJECT_BEGIN) {
311 return -1;
312 }
313
314 seen = calloc(sizeof(bool), num_decoders);
315 if (seen == NULL) {
316 return -1;
317 }
318
319 for (i = 0; i < values->len;) {
320 const struct spdk_json_val *name = &values[i + 1];
321 const struct spdk_json_val *v = &values[i + 2];
322 bool found = false;
323
324 for (decidx = 0; decidx < num_decoders; decidx++) {
325 const struct spdk_json_object_decoder *dec = &decoders[decidx];
326 if (spdk_json_strequal(name, dec->name)) {
327 void *field = (void *)((uintptr_t)out + dec->offset);
328
329 found = true;
330
331 if (seen[decidx]) {
332 /* duplicate field name */
333 invalid = true;
334 SPDK_JSON_DEBUG("Duplicate key '%s'\n", dec->name);
335 } else {
336 seen[decidx] = true;
337 if (dec->decode_func(v, field)) {
338 invalid = true;
339 SPDK_JSON_DEBUG("Decoder failed to decode key '%s'\n", dec->name);
340 /* keep going to fill out any other valid keys */
341 }
342 }
343 break;
344 }
345 }
346
347 if (!found) {
348 invalid = true;
349 SPDK_JSON_DEBUG("Decoder not found for key '%.*s'\n", name->len, (char *)name->start);
350 }
351
352 i += 1 + spdk_json_val_len(v);
353 }
354
355 for (decidx = 0; decidx < num_decoders; decidx++) {
356 if (!decoders[decidx].optional && !seen[decidx]) {
357 /* required field is missing */
358 invalid = true;
359 break;
360 }
361 }
362
363 free(seen);
364 return invalid ? -1 : 0;
365 }
366
367 int
368 spdk_json_decode_array(const struct spdk_json_val *values, spdk_json_decode_fn decode_func,
369 void *out, size_t max_size, size_t *out_size, size_t stride)
370 {
371 uint32_t i;
372 char *field;
373 char *out_end;
374
375 if (values == NULL || values->type != SPDK_JSON_VAL_ARRAY_BEGIN) {
376 return -1;
377 }
378
379 *out_size = 0;
380 field = out;
381 out_end = field + max_size * stride;
382 for (i = 0; i < values->len;) {
383 const struct spdk_json_val *v = &values[i + 1];
384
385 if (field == out_end) {
386 return -1;
387 }
388
389 if (decode_func(v, field)) {
390 return -1;
391 }
392
393 i += spdk_json_val_len(v);
394 field += stride;
395 (*out_size)++;
396 }
397
398 return 0;
399 }
400
401 int
402 spdk_json_decode_bool(const struct spdk_json_val *val, void *out)
403 {
404 bool *f = out;
405
406 if (val->type != SPDK_JSON_VAL_TRUE && val->type != SPDK_JSON_VAL_FALSE) {
407 return -1;
408 }
409
410 *f = val->type == SPDK_JSON_VAL_TRUE;
411 return 0;
412 }
413
414 int
415 spdk_json_decode_uint16(const struct spdk_json_val *val, void *out)
416 {
417 uint16_t *i = out;
418
419 return spdk_json_number_to_uint16(val, i);
420 }
421
422 int
423 spdk_json_decode_int32(const struct spdk_json_val *val, void *out)
424 {
425 int32_t *i = out;
426
427 return spdk_json_number_to_int32(val, i);
428 }
429
430 int
431 spdk_json_decode_uint32(const struct spdk_json_val *val, void *out)
432 {
433 uint32_t *i = out;
434
435 return spdk_json_number_to_uint32(val, i);
436 }
437
438 int
439 spdk_json_decode_uint64(const struct spdk_json_val *val, void *out)
440 {
441 uint64_t *i = out;
442
443 return spdk_json_number_to_uint64(val, i);
444 }
445
446 int
447 spdk_json_decode_string(const struct spdk_json_val *val, void *out)
448 {
449 char **s = out;
450
451 free(*s);
452
453 *s = spdk_json_strdup(val);
454
455 if (*s) {
456 return 0;
457 } else {
458 return -1;
459 }
460 }
461
462 static struct spdk_json_val *
463 spdk_json_first(struct spdk_json_val *object, enum spdk_json_val_type type)
464 {
465 /* 'object' must be JSON object or array. 'type' might be combination of these two. */
466 assert((type & (SPDK_JSON_VAL_ARRAY_BEGIN | SPDK_JSON_VAL_OBJECT_BEGIN)) != 0);
467
468 assert(object != NULL);
469
470 if ((object->type & type) == 0) {
471 return NULL;
472 }
473
474 object++;
475 if (object->len == 0) {
476 return NULL;
477 }
478
479 return object;
480 }
481
482 static struct spdk_json_val *
483 spdk_json_value(struct spdk_json_val *key)
484 {
485 return key->type == SPDK_JSON_VAL_NAME ? key + 1 : NULL;
486 }
487
488 int
489 spdk_json_find(struct spdk_json_val *object, const char *key_name, struct spdk_json_val **key,
490 struct spdk_json_val **val, enum spdk_json_val_type type)
491 {
492 struct spdk_json_val *_key = NULL;
493 struct spdk_json_val *_val = NULL;
494 struct spdk_json_val *it;
495
496 assert(object != NULL);
497
498 for (it = spdk_json_first(object, SPDK_JSON_VAL_ARRAY_BEGIN | SPDK_JSON_VAL_OBJECT_BEGIN);
499 it != NULL;
500 it = spdk_json_next(it)) {
501 if (it->type != SPDK_JSON_VAL_NAME) {
502 continue;
503 }
504
505 if (spdk_json_strequal(it, key_name) != true) {
506 continue;
507 }
508
509 if (_key) {
510 SPDK_JSON_DEBUG("Duplicate key '%s'", key_name);
511 return -EINVAL;
512 }
513
514 _key = it;
515 _val = spdk_json_value(_key);
516
517 if (type != SPDK_JSON_VAL_INVALID && (_val->type & type) == 0) {
518 SPDK_JSON_DEBUG("key '%s' type is %#x but expected one of %#x\n", key_name, _val->type, type);
519 return -EDOM;
520 }
521 }
522
523 if (key) {
524 *key = _key;
525 }
526
527 if (val) {
528 *val = _val;
529 }
530
531 return _val ? 0 : -ENOENT;
532 }
533
534 int
535 spdk_json_find_string(struct spdk_json_val *object, const char *key_name,
536 struct spdk_json_val **key, struct spdk_json_val **val)
537 {
538 return spdk_json_find(object, key_name, key, val, SPDK_JSON_VAL_STRING);
539 }
540
541 int
542 spdk_json_find_array(struct spdk_json_val *object, const char *key_name,
543 struct spdk_json_val **key, struct spdk_json_val **val)
544 {
545 return spdk_json_find(object, key_name, key, val, SPDK_JSON_VAL_ARRAY_BEGIN);
546 }
547
548 struct spdk_json_val *
549 spdk_json_object_first(struct spdk_json_val *object)
550 {
551 struct spdk_json_val *first = spdk_json_first(object, SPDK_JSON_VAL_OBJECT_BEGIN);
552
553 /* Empty object? */
554 return first && first->type != SPDK_JSON_VAL_OBJECT_END ? first : NULL;
555 }
556
557 struct spdk_json_val *
558 spdk_json_array_first(struct spdk_json_val *array_begin)
559 {
560 struct spdk_json_val *first = spdk_json_first(array_begin, SPDK_JSON_VAL_ARRAY_BEGIN);
561
562 /* Empty array? */
563 return first && first->type != SPDK_JSON_VAL_ARRAY_END ? first : NULL;
564 }
565
566 static struct spdk_json_val *
567 spdk_json_skip_object_or_array(struct spdk_json_val *val)
568 {
569 unsigned lvl;
570 enum spdk_json_val_type end_type;
571 struct spdk_json_val *it;
572
573 if (val->type == SPDK_JSON_VAL_OBJECT_BEGIN) {
574 end_type = SPDK_JSON_VAL_OBJECT_END;
575 } else if (val->type == SPDK_JSON_VAL_ARRAY_BEGIN) {
576 end_type = SPDK_JSON_VAL_ARRAY_END;
577 } else {
578 SPDK_JSON_DEBUG("Expected JSON object (%#x) or array (%#x) but got %#x\n",
579 SPDK_JSON_VAL_OBJECT_BEGIN, SPDK_JSON_VAL_ARRAY_BEGIN, val->type);
580 return NULL;
581 }
582
583 lvl = 1;
584 for (it = val + 1; it->type != SPDK_JSON_VAL_INVALID && lvl != 0; it++) {
585 if (it->type == val->type) {
586 lvl++;
587 } else if (it->type == end_type) {
588 lvl--;
589 }
590 }
591
592 /* if lvl != 0 we have invalid JSON object */
593 if (lvl != 0) {
594 SPDK_JSON_DEBUG("Can't find end of object (type: %#x): lvl (%u) != 0)\n", val->type, lvl);
595 it = NULL;
596 }
597
598 return it;
599 }
600
601 struct spdk_json_val *
602 spdk_json_next(struct spdk_json_val *it)
603 {
604 struct spdk_json_val *val, *next;
605
606 switch (it->type) {
607 case SPDK_JSON_VAL_NAME:
608 val = spdk_json_value(it);
609 next = spdk_json_next(val);
610 break;
611
612 /* We are in the middle of an array - get to next entry */
613 case SPDK_JSON_VAL_NULL:
614 case SPDK_JSON_VAL_TRUE:
615 case SPDK_JSON_VAL_FALSE:
616 case SPDK_JSON_VAL_NUMBER:
617 case SPDK_JSON_VAL_STRING:
618 val = it + 1;
619 return val;
620
621 case SPDK_JSON_VAL_ARRAY_BEGIN:
622 case SPDK_JSON_VAL_OBJECT_BEGIN:
623 next = spdk_json_skip_object_or_array(it);
624 break;
625
626 /* Can't go to the next object if started from the end of array or object */
627 case SPDK_JSON_VAL_ARRAY_END:
628 case SPDK_JSON_VAL_OBJECT_END:
629 case SPDK_JSON_VAL_INVALID:
630 return NULL;
631 default:
632 assert(false);
633 return NULL;
634
635 }
636
637 /* EOF ? */
638 if (next == NULL) {
639 return NULL;
640 }
641
642 switch (next->type) {
643 case SPDK_JSON_VAL_ARRAY_END:
644 case SPDK_JSON_VAL_OBJECT_END:
645 case SPDK_JSON_VAL_INVALID:
646 return NULL;
647 default:
648 /* Next value */
649 return next;
650 }
651 }
652
653 SPDK_LOG_REGISTER_COMPONENT("json_util", SPDK_LOG_JSON_UTIL)