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