1 /*
2 * Copyright (c) 2014-2020 Pavel Kalvoda <[email protected]>
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
claim_bytes(size_t required,size_t provided,struct cbor_decoder_result * result)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
cbor_stream_decode(cbor_data source,size_t source_size,const struct cbor_callbacks * callbacks,void * context)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