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
_cbor_claim_bytes(size_t required,size_t provided,struct cbor_decoder_result * result)11 bool 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
cbor_stream_decode(cbor_data source,size_t source_size,const struct cbor_callbacks * callbacks,void * context)26 struct 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