1 /* 2 * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com> 3 * 4 * libcbor is free software; you can redistribute it and/or modify 5 * it under the terms of the MIT license. See LICENSE for details. 6 */ 7 8 #include "streaming.h" 9 #include "internal/loaders.h" 10 11 static bool claim_bytes(size_t required, size_t provided, 12 struct cbor_decoder_result *result) { 13 if (required > (provided - result->read)) { 14 result->required = required + result->read; 15 result->read = 0; 16 result->status = CBOR_DECODER_NEDATA; 17 return false; 18 } else { 19 result->read += required; 20 result->required = 0; 21 return true; 22 } 23 } 24 25 // Use implicit capture as an exception to avoid the super long parameter list 26 #define CLAIM_BYTES_AND_INVOKE(callback_name, length, source_extra_offset) \ 27 do { \ 28 if (claim_bytes(length, source_size, &result)) { \ 29 callbacks->callback_name(context, source + 1 + source_extra_offset, \ 30 length); \ 31 } \ 32 } while (0) 33 34 #define READ_CLAIM_INVOKE(callback_name, length_reader, length_bytes) \ 35 do { \ 36 if (claim_bytes(length_bytes, source_size, &result)) { \ 37 uint64_t length = length_reader(source + 1); \ 38 CLAIM_BYTES_AND_INVOKE(callback_name, length, length_bytes); \ 39 } \ 40 return result; \ 41 } while (0) 42 43 struct cbor_decoder_result cbor_stream_decode( 44 cbor_data source, size_t source_size, 45 const struct cbor_callbacks *callbacks, void *context) { 46 // Attempt to claim the initial MTB byte 47 struct cbor_decoder_result result = {.status = CBOR_DECODER_FINISHED}; 48 if (!claim_bytes(1, source_size, &result)) { 49 return result; 50 } 51 52 switch (*source) { 53 case 0x00: /* Fallthrough */ 54 case 0x01: /* Fallthrough */ 55 case 0x02: /* Fallthrough */ 56 case 0x03: /* Fallthrough */ 57 case 0x04: /* Fallthrough */ 58 case 0x05: /* Fallthrough */ 59 case 0x06: /* Fallthrough */ 60 case 0x07: /* Fallthrough */ 61 case 0x08: /* Fallthrough */ 62 case 0x09: /* Fallthrough */ 63 case 0x0A: /* Fallthrough */ 64 case 0x0B: /* Fallthrough */ 65 case 0x0C: /* Fallthrough */ 66 case 0x0D: /* Fallthrough */ 67 case 0x0E: /* Fallthrough */ 68 case 0x0F: /* Fallthrough */ 69 case 0x10: /* Fallthrough */ 70 case 0x11: /* Fallthrough */ 71 case 0x12: /* Fallthrough */ 72 case 0x13: /* Fallthrough */ 73 case 0x14: /* Fallthrough */ 74 case 0x15: /* Fallthrough */ 75 case 0x16: /* Fallthrough */ 76 case 0x17: 77 /* Embedded one byte unsigned integer */ 78 { 79 callbacks->uint8(context, _cbor_load_uint8(source)); 80 return result; 81 } 82 case 0x18: 83 /* One byte unsigned integer */ 84 { 85 if (claim_bytes(1, source_size, &result)) { 86 callbacks->uint8(context, _cbor_load_uint8(source + 1)); 87 } 88 return result; 89 } 90 case 0x19: 91 /* Two bytes unsigned integer */ 92 { 93 if (claim_bytes(2, source_size, &result)) { 94 callbacks->uint16(context, _cbor_load_uint16(source + 1)); 95 } 96 return result; 97 } 98 case 0x1A: 99 /* Four bytes unsigned integer */ 100 { 101 if (claim_bytes(4, source_size, &result)) { 102 callbacks->uint32(context, _cbor_load_uint32(source + 1)); 103 } 104 return result; 105 } 106 case 0x1B: 107 /* Eight bytes unsigned integer */ 108 { 109 if (claim_bytes(8, source_size, &result)) { 110 callbacks->uint64(context, _cbor_load_uint64(source + 1)); 111 } 112 return result; 113 } 114 case 0x1C: /* Fallthrough */ 115 case 0x1D: /* Fallthrough */ 116 case 0x1E: /* Fallthrough */ 117 case 0x1F: 118 /* Reserved */ 119 { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; } 120 case 0x20: /* Fallthrough */ 121 case 0x21: /* Fallthrough */ 122 case 0x22: /* Fallthrough */ 123 case 0x23: /* Fallthrough */ 124 case 0x24: /* Fallthrough */ 125 case 0x25: /* Fallthrough */ 126 case 0x26: /* Fallthrough */ 127 case 0x27: /* Fallthrough */ 128 case 0x28: /* Fallthrough */ 129 case 0x29: /* Fallthrough */ 130 case 0x2A: /* Fallthrough */ 131 case 0x2B: /* Fallthrough */ 132 case 0x2C: /* Fallthrough */ 133 case 0x2D: /* Fallthrough */ 134 case 0x2E: /* Fallthrough */ 135 case 0x2F: /* Fallthrough */ 136 case 0x30: /* Fallthrough */ 137 case 0x31: /* Fallthrough */ 138 case 0x32: /* Fallthrough */ 139 case 0x33: /* Fallthrough */ 140 case 0x34: /* Fallthrough */ 141 case 0x35: /* Fallthrough */ 142 case 0x36: /* Fallthrough */ 143 case 0x37: 144 /* Embedded one byte negative integer */ 145 { 146 callbacks->negint8(context, 147 _cbor_load_uint8(source) - 0x20); /* 0x20 offset */ 148 return result; 149 } 150 case 0x38: 151 /* One byte negative integer */ 152 { 153 if (claim_bytes(1, source_size, &result)) { 154 callbacks->negint8(context, _cbor_load_uint8(source + 1)); 155 } 156 return result; 157 } 158 case 0x39: 159 /* Two bytes negative integer */ 160 { 161 if (claim_bytes(2, source_size, &result)) { 162 callbacks->negint16(context, _cbor_load_uint16(source + 1)); 163 } 164 return result; 165 } 166 case 0x3A: 167 /* Four bytes negative integer */ 168 { 169 if (claim_bytes(4, source_size, &result)) { 170 callbacks->negint32(context, _cbor_load_uint32(source + 1)); 171 } 172 return result; 173 } 174 case 0x3B: 175 /* Eight bytes negative integer */ 176 { 177 if (claim_bytes(8, source_size, &result)) { 178 callbacks->negint64(context, _cbor_load_uint64(source + 1)); 179 } 180 return result; 181 } 182 case 0x3C: /* Fallthrough */ 183 case 0x3D: /* Fallthrough */ 184 case 0x3E: /* Fallthrough */ 185 case 0x3F: 186 /* Reserved */ 187 { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; } 188 case 0x40: /* Fallthrough */ 189 case 0x41: /* Fallthrough */ 190 case 0x42: /* Fallthrough */ 191 case 0x43: /* Fallthrough */ 192 case 0x44: /* Fallthrough */ 193 case 0x45: /* Fallthrough */ 194 case 0x46: /* Fallthrough */ 195 case 0x47: /* Fallthrough */ 196 case 0x48: /* Fallthrough */ 197 case 0x49: /* Fallthrough */ 198 case 0x4A: /* Fallthrough */ 199 case 0x4B: /* Fallthrough */ 200 case 0x4C: /* Fallthrough */ 201 case 0x4D: /* Fallthrough */ 202 case 0x4E: /* Fallthrough */ 203 case 0x4F: /* Fallthrough */ 204 case 0x50: /* Fallthrough */ 205 case 0x51: /* Fallthrough */ 206 case 0x52: /* Fallthrough */ 207 case 0x53: /* Fallthrough */ 208 case 0x54: /* Fallthrough */ 209 case 0x55: /* Fallthrough */ 210 case 0x56: /* Fallthrough */ 211 case 0x57: 212 /* Embedded length byte string */ 213 { 214 uint64_t length = _cbor_load_uint8(source) - 0x40; /* 0x40 offset */ 215 CLAIM_BYTES_AND_INVOKE(byte_string, length, 0); 216 return result; 217 } 218 case 0x58: 219 /* One byte length byte string */ 220 READ_CLAIM_INVOKE(byte_string, _cbor_load_uint8, 1); 221 case 0x59: 222 /* Two bytes length byte string */ 223 READ_CLAIM_INVOKE(byte_string, _cbor_load_uint16, 2); 224 case 0x5A: 225 /* Four bytes length byte string */ 226 READ_CLAIM_INVOKE(byte_string, _cbor_load_uint32, 4); 227 case 0x5B: 228 /* Eight bytes length byte string */ 229 READ_CLAIM_INVOKE(byte_string, _cbor_load_uint64, 8); 230 case 0x5C: /* Fallthrough */ 231 case 0x5D: /* Fallthrough */ 232 case 0x5E: 233 /* Reserved */ 234 { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; } 235 case 0x5F: 236 /* Indefinite byte string */ 237 { 238 callbacks->byte_string_start(context); 239 return result; 240 } 241 case 0x60: /* Fallthrough */ 242 case 0x61: /* Fallthrough */ 243 case 0x62: /* Fallthrough */ 244 case 0x63: /* Fallthrough */ 245 case 0x64: /* Fallthrough */ 246 case 0x65: /* Fallthrough */ 247 case 0x66: /* Fallthrough */ 248 case 0x67: /* Fallthrough */ 249 case 0x68: /* Fallthrough */ 250 case 0x69: /* Fallthrough */ 251 case 0x6A: /* Fallthrough */ 252 case 0x6B: /* Fallthrough */ 253 case 0x6C: /* Fallthrough */ 254 case 0x6D: /* Fallthrough */ 255 case 0x6E: /* Fallthrough */ 256 case 0x6F: /* Fallthrough */ 257 case 0x70: /* Fallthrough */ 258 case 0x71: /* Fallthrough */ 259 case 0x72: /* Fallthrough */ 260 case 0x73: /* Fallthrough */ 261 case 0x74: /* Fallthrough */ 262 case 0x75: /* Fallthrough */ 263 case 0x76: /* Fallthrough */ 264 case 0x77: 265 /* Embedded one byte length string */ 266 { 267 uint64_t length = _cbor_load_uint8(source) - 0x60; /* 0x60 offset */ 268 CLAIM_BYTES_AND_INVOKE(string, length, 0); 269 return result; 270 } 271 case 0x78: 272 /* One byte length string */ 273 READ_CLAIM_INVOKE(string, _cbor_load_uint8, 1); 274 case 0x79: 275 /* Two bytes length string */ 276 READ_CLAIM_INVOKE(string, _cbor_load_uint16, 2); 277 case 0x7A: 278 /* Four bytes length string */ 279 READ_CLAIM_INVOKE(string, _cbor_load_uint32, 4); 280 case 0x7B: 281 /* Eight bytes length string */ 282 READ_CLAIM_INVOKE(string, _cbor_load_uint64, 8); 283 case 0x7C: /* Fallthrough */ 284 case 0x7D: /* Fallthrough */ 285 case 0x7E: 286 /* Reserved */ 287 { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; } 288 case 0x7F: 289 /* Indefinite length string */ 290 { 291 callbacks->string_start(context); 292 return result; 293 } 294 case 0x80: /* Fallthrough */ 295 case 0x81: /* Fallthrough */ 296 case 0x82: /* Fallthrough */ 297 case 0x83: /* Fallthrough */ 298 case 0x84: /* Fallthrough */ 299 case 0x85: /* Fallthrough */ 300 case 0x86: /* Fallthrough */ 301 case 0x87: /* Fallthrough */ 302 case 0x88: /* Fallthrough */ 303 case 0x89: /* Fallthrough */ 304 case 0x8A: /* Fallthrough */ 305 case 0x8B: /* Fallthrough */ 306 case 0x8C: /* Fallthrough */ 307 case 0x8D: /* Fallthrough */ 308 case 0x8E: /* Fallthrough */ 309 case 0x8F: /* Fallthrough */ 310 case 0x90: /* Fallthrough */ 311 case 0x91: /* Fallthrough */ 312 case 0x92: /* Fallthrough */ 313 case 0x93: /* Fallthrough */ 314 case 0x94: /* Fallthrough */ 315 case 0x95: /* Fallthrough */ 316 case 0x96: /* Fallthrough */ 317 case 0x97: 318 /* Embedded one byte length array */ 319 { 320 callbacks->array_start( 321 context, _cbor_load_uint8(source) - 0x80); /* 0x40 offset */ 322 return result; 323 } 324 case 0x98: 325 /* One byte length array */ 326 { 327 if (claim_bytes(1, source_size, &result)) { 328 callbacks->array_start(context, _cbor_load_uint8(source + 1)); 329 } 330 return result; 331 } 332 case 0x99: 333 /* Two bytes length array */ 334 { 335 if (claim_bytes(2, source_size, &result)) { 336 callbacks->array_start(context, _cbor_load_uint16(source + 1)); 337 } 338 return result; 339 } 340 case 0x9A: 341 /* Four bytes length array */ 342 { 343 if (claim_bytes(4, source_size, &result)) { 344 callbacks->array_start(context, _cbor_load_uint32(source + 1)); 345 } 346 return result; 347 } 348 case 0x9B: 349 /* Eight bytes length array */ 350 { 351 if (claim_bytes(8, source_size, &result)) { 352 callbacks->array_start(context, _cbor_load_uint64(source + 1)); 353 } 354 return result; 355 } 356 case 0x9C: /* Fallthrough */ 357 case 0x9D: /* Fallthrough */ 358 case 0x9E: 359 /* Reserved */ 360 { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; } 361 case 0x9F: 362 /* Indefinite length array */ 363 { 364 callbacks->indef_array_start(context); 365 return result; 366 } 367 case 0xA0: /* Fallthrough */ 368 case 0xA1: /* Fallthrough */ 369 case 0xA2: /* Fallthrough */ 370 case 0xA3: /* Fallthrough */ 371 case 0xA4: /* Fallthrough */ 372 case 0xA5: /* Fallthrough */ 373 case 0xA6: /* Fallthrough */ 374 case 0xA7: /* Fallthrough */ 375 case 0xA8: /* Fallthrough */ 376 case 0xA9: /* Fallthrough */ 377 case 0xAA: /* Fallthrough */ 378 case 0xAB: /* Fallthrough */ 379 case 0xAC: /* Fallthrough */ 380 case 0xAD: /* Fallthrough */ 381 case 0xAE: /* Fallthrough */ 382 case 0xAF: /* Fallthrough */ 383 case 0xB0: /* Fallthrough */ 384 case 0xB1: /* Fallthrough */ 385 case 0xB2: /* Fallthrough */ 386 case 0xB3: /* Fallthrough */ 387 case 0xB4: /* Fallthrough */ 388 case 0xB5: /* Fallthrough */ 389 case 0xB6: /* Fallthrough */ 390 case 0xB7: 391 /* Embedded one byte length map */ 392 { 393 callbacks->map_start(context, 394 _cbor_load_uint8(source) - 0xA0); /* 0xA0 offset */ 395 return result; 396 } 397 case 0xB8: 398 /* One byte length map */ 399 { 400 if (claim_bytes(1, source_size, &result)) { 401 callbacks->map_start(context, _cbor_load_uint8(source + 1)); 402 } 403 return result; 404 } 405 case 0xB9: 406 /* Two bytes length map */ 407 { 408 if (claim_bytes(2, source_size, &result)) { 409 callbacks->map_start(context, _cbor_load_uint16(source + 1)); 410 } 411 return result; 412 } 413 case 0xBA: 414 /* Four bytes length map */ 415 { 416 if (claim_bytes(4, source_size, &result)) { 417 callbacks->map_start(context, _cbor_load_uint32(source + 1)); 418 } 419 return result; 420 } 421 case 0xBB: 422 /* Eight bytes length map */ 423 { 424 if (claim_bytes(8, source_size, &result)) { 425 callbacks->map_start(context, _cbor_load_uint64(source + 1)); 426 } 427 return result; 428 } 429 case 0xBC: /* Fallthrough */ 430 case 0xBD: /* Fallthrough */ 431 case 0xBE: 432 /* Reserved */ 433 { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; } 434 case 0xBF: 435 /* Indefinite length map */ 436 { 437 callbacks->indef_map_start(context); 438 return result; 439 } 440 case 0xC0: 441 /* Text date/time - RFC 3339 tag, fallthrough */ 442 case 0xC1: 443 /* Epoch date tag, fallthrough */ 444 case 0xC2: 445 /* Positive bignum tag, fallthrough */ 446 case 0xC3: 447 /* Negative bignum tag, fallthrough */ 448 case 0xC4: 449 /* Fraction, fallthrough */ 450 case 0xC5: 451 /* Big float */ 452 { 453 callbacks->tag(context, (uint64_t)(_cbor_load_uint8(source) - 454 0xC0)); /* 0xC0 offset */ 455 return result; 456 } 457 case 0xC6: /* Fallthrough */ 458 case 0xC7: /* Fallthrough */ 459 case 0xC8: /* Fallthrough */ 460 case 0xC9: /* Fallthrough */ 461 case 0xCA: /* Fallthrough */ 462 case 0xCB: /* Fallthrough */ 463 case 0xCC: /* Fallthrough */ 464 case 0xCD: /* Fallthrough */ 465 case 0xCE: /* Fallthrough */ 466 case 0xCF: /* Fallthrough */ 467 case 0xD0: /* Fallthrough */ 468 case 0xD1: /* Fallthrough */ 469 case 0xD2: /* Fallthrough */ 470 case 0xD3: /* Fallthrough */ 471 case 0xD4: /* Unassigned tag value */ 472 { 473 return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; 474 } 475 case 0xD5: /* Expected b64url conversion tag - fallthrough */ 476 case 0xD6: /* Expected b64 conversion tag - fallthrough */ 477 case 0xD7: /* Expected b16 conversion tag */ 478 { 479 callbacks->tag(context, (uint64_t)(_cbor_load_uint8(source) - 480 0xC0)); /* 0xC0 offset */ 481 return result; 482 } 483 case 0xD8: /* 1B tag */ 484 { 485 if (claim_bytes(1, source_size, &result)) { 486 callbacks->tag(context, _cbor_load_uint8(source + 1)); 487 } 488 return result; 489 } 490 case 0xD9: /* 2B tag */ 491 { 492 if (claim_bytes(2, source_size, &result)) { 493 callbacks->tag(context, _cbor_load_uint16(source + 1)); 494 } 495 return result; 496 } 497 case 0xDA: /* 4B tag */ 498 { 499 if (claim_bytes(4, source_size, &result)) { 500 callbacks->tag(context, _cbor_load_uint32(source + 1)); 501 } 502 return result; 503 } 504 case 0xDB: /* 8B tag */ 505 { 506 if (claim_bytes(8, source_size, &result)) { 507 callbacks->tag(context, _cbor_load_uint64(source + 1)); 508 } 509 return result; 510 } 511 case 0xDC: /* Fallthrough */ 512 case 0xDD: /* Fallthrough */ 513 case 0xDE: /* Fallthrough */ 514 case 0xDF: /* Reserved */ 515 { 516 return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; 517 } 518 case 0xE0: /* Fallthrough */ 519 case 0xE1: /* Fallthrough */ 520 case 0xE2: /* Fallthrough */ 521 case 0xE3: /* Fallthrough */ 522 case 0xE4: /* Fallthrough */ 523 case 0xE5: /* Fallthrough */ 524 case 0xE6: /* Fallthrough */ 525 case 0xE7: /* Fallthrough */ 526 case 0xE8: /* Fallthrough */ 527 case 0xE9: /* Fallthrough */ 528 case 0xEA: /* Fallthrough */ 529 case 0xEB: /* Fallthrough */ 530 case 0xEC: /* Fallthrough */ 531 case 0xED: /* Fallthrough */ 532 case 0xEE: /* Fallthrough */ 533 case 0xEF: /* Fallthrough */ 534 case 0xF0: /* Fallthrough */ 535 case 0xF1: /* Fallthrough */ 536 case 0xF2: /* Fallthrough */ 537 case 0xF3: /* Simple value - unassigned */ 538 { 539 return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; 540 } 541 case 0xF4: 542 /* False */ 543 { 544 callbacks->boolean(context, false); 545 return result; 546 } 547 case 0xF5: 548 /* True */ 549 { 550 callbacks->boolean(context, true); 551 return result; 552 } 553 case 0xF6: 554 /* Null */ 555 { 556 callbacks->null(context); 557 return result; 558 } 559 case 0xF7: 560 /* Undefined */ 561 { 562 callbacks->undefined(context); 563 return result; 564 } 565 case 0xF8: 566 /* 1B simple value, unassigned */ 567 { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; } 568 case 0xF9: 569 /* 2B float */ 570 { 571 if (claim_bytes(2, source_size, &result)) { 572 callbacks->float2(context, _cbor_load_half(source + 1)); 573 } 574 return result; 575 } 576 case 0xFA: 577 /* 4B float */ 578 { 579 if (claim_bytes(4, source_size, &result)) { 580 callbacks->float4(context, _cbor_load_float(source + 1)); 581 } 582 return result; 583 } 584 case 0xFB: 585 /* 8B float */ 586 { 587 if (claim_bytes(8, source_size, &result)) { 588 callbacks->float8(context, _cbor_load_double(source + 1)); 589 } 590 return result; 591 } 592 case 0xFC: /* Fallthrough */ 593 case 0xFD: /* Fallthrough */ 594 case 0xFE: 595 /* Reserved */ 596 { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; } 597 case 0xFF: 598 /* Break */ 599 callbacks->indef_break(context); 600 // Never happens, the switch statement is exhaustive on the 1B range; make 601 // compiler happy 602 default: 603 return result; 604 } 605 } 606