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