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
11static 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
43struct 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