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 "json_internal.h" 35 36 size_t 37 spdk_json_val_len(const struct spdk_json_val *val) 38 { 39 if (val == NULL) { 40 return 0; 41 } 42 43 if (val->type == SPDK_JSON_VAL_ARRAY_BEGIN || val->type == SPDK_JSON_VAL_OBJECT_BEGIN) { 44 return val->len + 2; 45 } 46 47 return 1; 48 } 49 50 bool 51 spdk_json_strequal(const struct spdk_json_val *val, const char *str) 52 { 53 size_t len; 54 55 if (val->type != SPDK_JSON_VAL_STRING && val->type != SPDK_JSON_VAL_NAME) { 56 return false; 57 } 58 59 len = strlen(str); 60 if (val->len != len) { 61 return false; 62 } 63 64 return memcmp(val->start, str, len) == 0; 65 } 66 67 char * 68 spdk_json_strdup(const struct spdk_json_val *val) 69 { 70 size_t len; 71 char *s; 72 73 if (val->type != SPDK_JSON_VAL_STRING && val->type != SPDK_JSON_VAL_NAME) { 74 return NULL; 75 } 76 77 len = val->len; 78 79 if (memchr(val->start, '\0', len)) { 80 /* String contains embedded NUL, so it is not a valid C string. */ 81 return NULL; 82 } 83 84 s = malloc(len + 1); 85 if (s == NULL) { 86 return s; 87 } 88 89 memcpy(s, val->start, len); 90 s[len] = '\0'; 91 92 return s; 93 } 94 95 struct spdk_json_num { 96 bool negative; 97 uint64_t significand; 98 int64_t exponent; 99 }; 100 101 static int 102 spdk_json_number_split(const struct spdk_json_val *val, struct spdk_json_num *num) 103 { 104 const char *iter; 105 size_t remaining; 106 uint64_t *pval; 107 uint64_t frac_digits = 0; 108 uint64_t exponent_u64 = 0; 109 bool exponent_negative = false; 110 enum { 111 NUM_STATE_INT, 112 NUM_STATE_FRAC, 113 NUM_STATE_EXP, 114 } state; 115 116 memset(num, 0, sizeof(*num)); 117 118 if (val->type != SPDK_JSON_VAL_NUMBER) { 119 return -EINVAL; 120 } 121 122 remaining = val->len; 123 if (remaining == 0) { 124 return -EINVAL; 125 } 126 127 iter = val->start; 128 if (*iter == '-') { 129 num->negative = true; 130 iter++; 131 remaining--; 132 } 133 134 state = NUM_STATE_INT; 135 pval = &num->significand; 136 while (remaining--) { 137 char c = *iter++; 138 139 if (c == '.') { 140 state = NUM_STATE_FRAC; 141 } else if (c == 'e' || c == 'E') { 142 state = NUM_STATE_EXP; 143 pval = &exponent_u64; 144 } else if (c == '-') { 145 assert(state == NUM_STATE_EXP); 146 exponent_negative = true; 147 } else if (c == '+') { 148 assert(state == NUM_STATE_EXP); 149 /* exp_negative = false; */ /* already false by default */ 150 } else { 151 uint64_t new_val; 152 153 assert(c >= '0' && c <= '9'); 154 new_val = *pval * 10 + c - '0'; 155 if (new_val < *pval) { 156 return -ERANGE; 157 } 158 159 if (state == NUM_STATE_FRAC) { 160 frac_digits++; 161 } 162 163 *pval = new_val; 164 } 165 } 166 167 if (exponent_negative) { 168 if (exponent_u64 > 9223372036854775808ULL) { /* abs(INT64_MIN) */ 169 return -ERANGE; 170 } 171 num->exponent = (int64_t) - exponent_u64; 172 } else { 173 if (exponent_u64 > INT64_MAX) { 174 return -ERANGE; 175 } 176 num->exponent = exponent_u64; 177 } 178 num->exponent -= frac_digits; 179 180 /* Apply as much of the exponent as possible without overflow or truncation */ 181 if (num->exponent < 0) { 182 while (num->exponent && num->significand >= 10 && num->significand % 10 == 0) { 183 num->significand /= 10; 184 num->exponent++; 185 } 186 } else { /* positive exponent */ 187 while (num->exponent) { 188 uint64_t new_val = num->significand * 10; 189 190 if (new_val < num->significand) { 191 break; 192 } 193 194 num->significand = new_val; 195 num->exponent--; 196 } 197 } 198 199 return 0; 200 } 201 202 int 203 spdk_json_number_to_int32(const struct spdk_json_val *val, int32_t *num) 204 { 205 struct spdk_json_num split_num; 206 int rc; 207 208 rc = spdk_json_number_split(val, &split_num); 209 if (rc) { 210 return rc; 211 } 212 213 if (split_num.exponent) { 214 return -ERANGE; 215 } 216 217 if (split_num.negative) { 218 if (split_num.significand > 2147483648) { /* abs(INT32_MIN) */ 219 return -ERANGE; 220 } 221 *num = (int32_t) - (int64_t)split_num.significand; 222 return 0; 223 } 224 225 /* positive */ 226 if (split_num.significand > INT32_MAX) { 227 return -ERANGE; 228 } 229 *num = (int32_t)split_num.significand; 230 return 0; 231 } 232 233 int 234 spdk_json_number_to_uint32(const struct spdk_json_val *val, uint32_t *num) 235 { 236 struct spdk_json_num split_num; 237 int rc; 238 239 rc = spdk_json_number_split(val, &split_num); 240 if (rc) { 241 return rc; 242 } 243 244 if (split_num.exponent || split_num.negative) { 245 return -ERANGE; 246 } 247 248 if (split_num.significand > UINT32_MAX) { 249 return -ERANGE; 250 } 251 *num = (uint32_t)split_num.significand; 252 return 0; 253 } 254 255 int 256 spdk_json_number_to_uint64(const struct spdk_json_val *val, uint64_t *num) 257 { 258 struct spdk_json_num split_num; 259 int rc; 260 261 rc = spdk_json_number_split(val, &split_num); 262 if (rc) { 263 return rc; 264 } 265 266 if (split_num.exponent || split_num.negative) { 267 return -ERANGE; 268 } 269 270 *num = split_num.significand; 271 return 0; 272 } 273 274 int 275 spdk_json_decode_object(const struct spdk_json_val *values, 276 const struct spdk_json_object_decoder *decoders, size_t num_decoders, void *out) 277 { 278 uint32_t i; 279 bool invalid = false; 280 size_t decidx; 281 bool *seen; 282 283 if (values == NULL || values->type != SPDK_JSON_VAL_OBJECT_BEGIN) { 284 return -1; 285 } 286 287 seen = calloc(sizeof(bool), num_decoders); 288 if (seen == NULL) { 289 return -1; 290 } 291 292 for (i = 0; i < values->len;) { 293 const struct spdk_json_val *name = &values[i + 1]; 294 const struct spdk_json_val *v = &values[i + 2]; 295 bool found = false; 296 297 for (decidx = 0; decidx < num_decoders; decidx++) { 298 const struct spdk_json_object_decoder *dec = &decoders[decidx]; 299 if (spdk_json_strequal(name, dec->name)) { 300 void *field = (void *)((uintptr_t)out + dec->offset); 301 302 found = true; 303 304 if (seen[decidx]) { 305 /* duplicate field name */ 306 invalid = true; 307 } else { 308 seen[decidx] = true; 309 if (dec->decode_func(v, field)) { 310 invalid = true; 311 /* keep going to fill out any other valid keys */ 312 } 313 } 314 break; 315 } 316 } 317 318 if (!found) { 319 invalid = true; 320 } 321 322 i += 1 + spdk_json_val_len(v); 323 } 324 325 for (decidx = 0; decidx < num_decoders; decidx++) { 326 if (!decoders[decidx].optional && !seen[decidx]) { 327 /* required field is missing */ 328 invalid = true; 329 break; 330 } 331 } 332 333 free(seen); 334 return invalid ? -1 : 0; 335 } 336 337 int 338 spdk_json_decode_array(const struct spdk_json_val *values, spdk_json_decode_fn decode_func, 339 void *out, size_t max_size, size_t *out_size, size_t stride) 340 { 341 uint32_t i; 342 char *field; 343 344 if (values == NULL || values->type != SPDK_JSON_VAL_ARRAY_BEGIN) { 345 return -1; 346 } 347 348 if (values->len > max_size) { 349 return -1; 350 } 351 352 *out_size = 0; 353 field = out; 354 for (i = 0; i < values->len;) { 355 const struct spdk_json_val *v = &values[i + 1]; 356 357 if (decode_func(v, field)) { 358 return -1; 359 } 360 361 i += spdk_json_val_len(v); 362 field += stride; 363 (*out_size)++; 364 } 365 366 return 0; 367 } 368 369 int 370 spdk_json_decode_bool(const struct spdk_json_val *val, void *out) 371 { 372 bool *f = out; 373 374 if (val->type != SPDK_JSON_VAL_TRUE && val->type != SPDK_JSON_VAL_FALSE) { 375 return -1; 376 } 377 378 *f = val->type == SPDK_JSON_VAL_TRUE; 379 return 0; 380 } 381 382 int 383 spdk_json_decode_int32(const struct spdk_json_val *val, void *out) 384 { 385 int32_t *i = out; 386 387 return spdk_json_number_to_int32(val, i); 388 } 389 390 int 391 spdk_json_decode_uint32(const struct spdk_json_val *val, void *out) 392 { 393 uint32_t *i = out; 394 395 return spdk_json_number_to_uint32(val, i); 396 } 397 398 int 399 spdk_json_decode_uint64(const struct spdk_json_val *val, void *out) 400 { 401 uint64_t *i = out; 402 403 return spdk_json_number_to_uint64(val, i); 404 } 405 406 int 407 spdk_json_decode_string(const struct spdk_json_val *val, void *out) 408 { 409 char **s = out; 410 411 free(*s); 412 413 *s = spdk_json_strdup(val); 414 415 if (*s) { 416 return 0; 417 } else { 418 return -1; 419 } 420 } 421