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_int32(const struct spdk_json_val *val, int32_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) { 216 return -ERANGE; 217 } 218 219 if (split_num.negative) { 220 if (split_num.significand > 2147483648) { /* abs(INT32_MIN) */ 221 return -ERANGE; 222 } 223 *num = (int32_t) - (int64_t)split_num.significand; 224 return 0; 225 } 226 227 /* positive */ 228 if (split_num.significand > INT32_MAX) { 229 return -ERANGE; 230 } 231 *num = (int32_t)split_num.significand; 232 return 0; 233 } 234 235 int 236 spdk_json_number_to_uint32(const struct spdk_json_val *val, uint32_t *num) 237 { 238 struct spdk_json_num split_num; 239 int rc; 240 241 rc = spdk_json_number_split(val, &split_num); 242 if (rc) { 243 return rc; 244 } 245 246 if (split_num.exponent || split_num.negative) { 247 return -ERANGE; 248 } 249 250 if (split_num.significand > UINT32_MAX) { 251 return -ERANGE; 252 } 253 *num = (uint32_t)split_num.significand; 254 return 0; 255 } 256 257 int 258 spdk_json_number_to_uint64(const struct spdk_json_val *val, uint64_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 *num = split_num.significand; 273 return 0; 274 } 275 276 int 277 spdk_json_decode_object(const struct spdk_json_val *values, 278 const struct spdk_json_object_decoder *decoders, size_t num_decoders, void *out) 279 { 280 uint32_t i; 281 bool invalid = false; 282 size_t decidx; 283 bool *seen; 284 285 if (values == NULL || values->type != SPDK_JSON_VAL_OBJECT_BEGIN) { 286 return -1; 287 } 288 289 seen = calloc(sizeof(bool), num_decoders); 290 if (seen == NULL) { 291 return -1; 292 } 293 294 for (i = 0; i < values->len;) { 295 const struct spdk_json_val *name = &values[i + 1]; 296 const struct spdk_json_val *v = &values[i + 2]; 297 bool found = false; 298 299 for (decidx = 0; decidx < num_decoders; decidx++) { 300 const struct spdk_json_object_decoder *dec = &decoders[decidx]; 301 if (spdk_json_strequal(name, dec->name)) { 302 void *field = (void *)((uintptr_t)out + dec->offset); 303 304 found = true; 305 306 if (seen[decidx]) { 307 /* duplicate field name */ 308 invalid = true; 309 } else { 310 seen[decidx] = true; 311 if (dec->decode_func(v, field)) { 312 invalid = true; 313 /* keep going to fill out any other valid keys */ 314 } 315 } 316 break; 317 } 318 } 319 320 if (!found) { 321 invalid = true; 322 } 323 324 i += 1 + spdk_json_val_len(v); 325 } 326 327 for (decidx = 0; decidx < num_decoders; decidx++) { 328 if (!decoders[decidx].optional && !seen[decidx]) { 329 /* required field is missing */ 330 invalid = true; 331 break; 332 } 333 } 334 335 free(seen); 336 return invalid ? -1 : 0; 337 } 338 339 int 340 spdk_json_decode_array(const struct spdk_json_val *values, spdk_json_decode_fn decode_func, 341 void *out, size_t max_size, size_t *out_size, size_t stride) 342 { 343 uint32_t i; 344 char *field; 345 char *out_end; 346 347 if (values == NULL || values->type != SPDK_JSON_VAL_ARRAY_BEGIN) { 348 return -1; 349 } 350 351 *out_size = 0; 352 field = out; 353 out_end = field + max_size * stride; 354 for (i = 0; i < values->len;) { 355 const struct spdk_json_val *v = &values[i + 1]; 356 357 if (field == out_end) { 358 return -1; 359 } 360 361 if (decode_func(v, field)) { 362 return -1; 363 } 364 365 i += spdk_json_val_len(v); 366 field += stride; 367 (*out_size)++; 368 } 369 370 return 0; 371 } 372 373 int 374 spdk_json_decode_bool(const struct spdk_json_val *val, void *out) 375 { 376 bool *f = out; 377 378 if (val->type != SPDK_JSON_VAL_TRUE && val->type != SPDK_JSON_VAL_FALSE) { 379 return -1; 380 } 381 382 *f = val->type == SPDK_JSON_VAL_TRUE; 383 return 0; 384 } 385 386 int 387 spdk_json_decode_int32(const struct spdk_json_val *val, void *out) 388 { 389 int32_t *i = out; 390 391 return spdk_json_number_to_int32(val, i); 392 } 393 394 int 395 spdk_json_decode_uint32(const struct spdk_json_val *val, void *out) 396 { 397 uint32_t *i = out; 398 399 return spdk_json_number_to_uint32(val, i); 400 } 401 402 int 403 spdk_json_decode_uint64(const struct spdk_json_val *val, void *out) 404 { 405 uint64_t *i = out; 406 407 return spdk_json_number_to_uint64(val, i); 408 } 409 410 int 411 spdk_json_decode_string(const struct spdk_json_val *val, void *out) 412 { 413 char **s = out; 414 415 free(*s); 416 417 *s = spdk_json_strdup(val); 418 419 if (*s) { 420 return 0; 421 } else { 422 return -1; 423 } 424 } 425