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 /* See https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml for tag 441 * assignment. All well-formed tags are processed regardless of validity 442 * since maintaining the known mapping would be impractical. 443 * 444 * Moreover, even tags in the reserved "standard" range are not assigned 445 * but may get assigned in the future (see e.g. 446 * https://github.com/PJK/libcbor/issues/307), so processing all tags 447 * improves forward compatibility. 448 */ 449 case 0xC0: /* Fallthrough */ 450 case 0xC1: /* Fallthrough */ 451 case 0xC2: /* Fallthrough */ 452 case 0xC3: /* Fallthrough */ 453 case 0xC4: /* Fallthrough */ 454 case 0xC5: /* Fallthrough */ 455 case 0xC6: /* Fallthrough */ 456 case 0xC7: /* Fallthrough */ 457 case 0xC8: /* Fallthrough */ 458 case 0xC9: /* Fallthrough */ 459 case 0xCA: /* Fallthrough */ 460 case 0xCB: /* Fallthrough */ 461 case 0xCC: /* Fallthrough */ 462 case 0xCD: /* Fallthrough */ 463 case 0xCE: /* Fallthrough */ 464 case 0xCF: /* Fallthrough */ 465 case 0xD0: /* Fallthrough */ 466 case 0xD1: /* Fallthrough */ 467 case 0xD2: /* Fallthrough */ 468 case 0xD3: /* Fallthrough */ 469 case 0xD4: /* Fallthrough */ 470 case 0xD5: /* Fallthrough */ 471 case 0xD6: /* Fallthrough */ 472 case 0xD7: /* Fallthrough */ 473 { 474 callbacks->tag(context, (uint64_t)(_cbor_load_uint8(source) - 475 0xC0)); /* 0xC0 offset */ 476 return result; 477 } 478 case 0xD8: /* 1B tag */ 479 { 480 if (claim_bytes(1, source_size, &result)) { 481 callbacks->tag(context, _cbor_load_uint8(source + 1)); 482 } 483 return result; 484 } 485 case 0xD9: /* 2B tag */ 486 { 487 if (claim_bytes(2, source_size, &result)) { 488 callbacks->tag(context, _cbor_load_uint16(source + 1)); 489 } 490 return result; 491 } 492 case 0xDA: /* 4B tag */ 493 { 494 if (claim_bytes(4, source_size, &result)) { 495 callbacks->tag(context, _cbor_load_uint32(source + 1)); 496 } 497 return result; 498 } 499 case 0xDB: /* 8B tag */ 500 { 501 if (claim_bytes(8, source_size, &result)) { 502 callbacks->tag(context, _cbor_load_uint64(source + 1)); 503 } 504 return result; 505 } 506 case 0xDC: /* Fallthrough */ 507 case 0xDD: /* Fallthrough */ 508 case 0xDE: /* Fallthrough */ 509 case 0xDF: /* Reserved */ 510 { 511 return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; 512 } 513 case 0xE0: /* Fallthrough */ 514 case 0xE1: /* Fallthrough */ 515 case 0xE2: /* Fallthrough */ 516 case 0xE3: /* Fallthrough */ 517 case 0xE4: /* Fallthrough */ 518 case 0xE5: /* Fallthrough */ 519 case 0xE6: /* Fallthrough */ 520 case 0xE7: /* Fallthrough */ 521 case 0xE8: /* Fallthrough */ 522 case 0xE9: /* Fallthrough */ 523 case 0xEA: /* Fallthrough */ 524 case 0xEB: /* Fallthrough */ 525 case 0xEC: /* Fallthrough */ 526 case 0xED: /* Fallthrough */ 527 case 0xEE: /* Fallthrough */ 528 case 0xEF: /* Fallthrough */ 529 case 0xF0: /* Fallthrough */ 530 case 0xF1: /* Fallthrough */ 531 case 0xF2: /* Fallthrough */ 532 case 0xF3: /* Simple value - unassigned */ 533 { 534 return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; 535 } 536 case 0xF4: 537 /* False */ 538 { 539 callbacks->boolean(context, false); 540 return result; 541 } 542 case 0xF5: 543 /* True */ 544 { 545 callbacks->boolean(context, true); 546 return result; 547 } 548 case 0xF6: 549 /* Null */ 550 { 551 callbacks->null(context); 552 return result; 553 } 554 case 0xF7: 555 /* Undefined */ 556 { 557 callbacks->undefined(context); 558 return result; 559 } 560 case 0xF8: 561 /* 1B simple value, unassigned */ 562 { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; } 563 case 0xF9: 564 /* 2B float */ 565 { 566 if (claim_bytes(2, source_size, &result)) { 567 callbacks->float2(context, _cbor_load_half(source + 1)); 568 } 569 return result; 570 } 571 case 0xFA: 572 /* 4B float */ 573 { 574 if (claim_bytes(4, source_size, &result)) { 575 callbacks->float4(context, _cbor_load_float(source + 1)); 576 } 577 return result; 578 } 579 case 0xFB: 580 /* 8B float */ 581 { 582 if (claim_bytes(8, source_size, &result)) { 583 callbacks->float8(context, _cbor_load_double(source + 1)); 584 } 585 return result; 586 } 587 case 0xFC: /* Fallthrough */ 588 case 0xFD: /* Fallthrough */ 589 case 0xFE: 590 /* Reserved */ 591 { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; } 592 case 0xFF: 593 /* Break */ 594 callbacks->indef_break(context); 595 // Never happens, the switch statement is exhaustive on the 1B range; make 596 // compiler happy 597 default: 598 return result; 599 } 600 } 601