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