Merge branch 'upstream' into tizen
[platform/upstream/iotivity.git] / extlibs / tinycbor / tinycbor / src / cborparser.c
1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 Intel Corporation
4 **
5 ** Permission is hereby granted, free of charge, to any person obtaining a copy
6 ** of this software and associated documentation files (the "Software"), to deal
7 ** in the Software without restriction, including without limitation the rights
8 ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 ** copies of the Software, and to permit persons to whom the Software is
10 ** furnished to do so, subject to the following conditions:
11 **
12 ** The above copyright notice and this permission notice shall be included in
13 ** all copies or substantial portions of the Software.
14 **
15 ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 ** THE SOFTWARE.
22 **
23 ****************************************************************************/
24
25 #define _BSD_SOURCE 1
26 #include "cbor.h"
27 #include "cborconstants_p.h"
28 #include "compilersupport_p.h"
29 #include "extract_number_p.h"
30
31 #include <assert.h>
32 #include <stdlib.h>
33 #include <string.h>
34
35 #include "assert_p.h"       /* Always include last */
36
37 #ifndef CBOR_PARSER_MAX_RECURSIONS
38 #  define CBOR_PARSER_MAX_RECURSIONS 1024
39 #endif
40
41 /**
42  * \typedef CborValue
43  * This type contains one value parsed from the CBOR stream.
44  *
45  * To get the actual type, use cbor_value_get_type(). Then extract the value
46  * using one of the corresponding functions: cbor_value_get_boolean(), cbor_value_get_int64(),
47  * cbor_value_get_int(), cbor_value_copy_string(), cbor_value_get_array(), cbor_value_get_map(),
48  * cbor_value_get_double(), cbor_value_get_float().
49  *
50  * In C++ and C11 modes, you can additionally use the cbor_value_get_integer()
51  * and cbor_value_get_floating_point() generic functions.
52  *
53  * \omit
54  * Implementation details: the CborValue contains these fields:
55  * \list
56  *   \li ptr: pointer to the actual data
57  *   \li flags: flags from the decoder
58  *   \li extra: partially decoded integer value (0, 1 or 2 bytes)
59  *   \li remaining: remaining items in this collection after this item or UINT32_MAX if length is unknown
60  * \endlist
61  * \endomit
62  */
63
64 static CborError extract_length(const CborParser *parser, const uint8_t **ptr, size_t *len)
65 {
66     uint64_t v;
67     CborError err = extract_number(ptr, parser->end, &v);
68     if (err) {
69         *len = 0;
70         return err;
71     }
72
73     *len = v;
74     if (v != *len)
75         return CborErrorDataTooLarge;
76     return CborNoError;
77 }
78
79 static bool is_fixed_type(uint8_t type)
80 {
81     return type != CborTextStringType && type != CborByteStringType && type != CborArrayType &&
82            type != CborMapType;
83 }
84
85 static CborError preparse_value(CborValue *it)
86 {
87     const CborParser *parser = it->parser;
88     it->type = CborInvalidType;
89
90     // are we at the end?
91     if (it->ptr == parser->end)
92         return CborErrorUnexpectedEOF;
93
94     uint8_t descriptor = *it->ptr;
95     uint8_t type = descriptor & MajorTypeMask;
96     it->type = type;
97     it->flags = 0;
98     it->extra = (descriptor &= SmallValueMask);
99
100     if (descriptor > Value64Bit) {
101         if (unlikely(descriptor != IndefiniteLength))
102             return type == CborSimpleType ? CborErrorUnknownType : CborErrorIllegalNumber;
103         if (likely(!is_fixed_type(type))) {
104             // special case
105             it->flags |= CborIteratorFlag_UnknownLength;
106             it->type = type;
107             return CborNoError;
108         }
109         return type == CborSimpleType ? CborErrorUnexpectedBreak : CborErrorIllegalNumber;
110     }
111
112     size_t bytesNeeded = descriptor < Value8Bit ? 0 : (1 << (descriptor - Value8Bit));
113     if (bytesNeeded + 1 > (size_t)(parser->end - it->ptr))
114         return CborErrorUnexpectedEOF;
115
116     uint8_t majortype = type >> MajorTypeShift;
117     if (majortype == NegativeIntegerType) {
118         it->flags |= CborIteratorFlag_NegativeInteger;
119         it->type = CborIntegerType;
120     } else if (majortype == SimpleTypesType) {
121         switch (descriptor) {
122         case FalseValue:
123             it->extra = false;
124             it->type = CborBooleanType;
125             break;
126
127         case SinglePrecisionFloat:
128         case DoublePrecisionFloat:
129             it->flags |= CborIteratorFlag_IntegerValueTooLarge;
130             // fall through
131         case TrueValue:
132         case NullValue:
133         case UndefinedValue:
134         case HalfPrecisionFloat:
135             it->type = *it->ptr;
136             break;
137
138         case SimpleTypeInNextByte:
139             it->extra = (uint8_t)it->ptr[1];
140 #ifndef CBOR_PARSER_NO_STRICT_CHECKS
141             if (unlikely(it->extra < 32)) {
142                 it->type = CborInvalidType;
143                 return CborErrorIllegalSimpleType;
144             }
145 #endif
146             break;
147
148         case 28:
149         case 29:
150         case 30:
151         case Break:
152             assert(false);  // these conditions can't be reached
153             return CborErrorUnexpectedBreak;
154         }
155         return CborNoError;
156     }
157
158     // try to decode up to 16 bits
159     if (descriptor < Value8Bit)
160         return CborNoError;
161
162     if (descriptor == Value8Bit)
163         it->extra = (uint8_t)it->ptr[1];
164     else if (descriptor == Value16Bit)
165         it->extra = get16(it->ptr + 1);
166     else
167         it->flags |= CborIteratorFlag_IntegerValueTooLarge;     // Value32Bit or Value64Bit
168     return CborNoError;
169 }
170
171 static CborError preparse_next_value(CborValue *it)
172 {
173     if (it->remaining != UINT32_MAX) {
174         // don't decrement the item count if the current item is tag: they don't count
175         if (it->type != CborTagType && !--it->remaining) {
176             it->type = CborInvalidType;
177             return CborNoError;
178         }
179     } else if (it->remaining == UINT32_MAX && it->ptr != it->parser->end && *it->ptr == (uint8_t)BreakByte) {
180         // end of map or array
181         ++it->ptr;
182         it->type = CborInvalidType;
183         it->remaining = 0;
184         return CborNoError;
185     }
186
187     return preparse_value(it);
188 }
189
190 static CborError advance_internal(CborValue *it)
191 {
192     uint64_t length;
193     CborError err = extract_number(&it->ptr, it->parser->end, &length);
194     assert(err == CborNoError);
195
196     if (it->type == CborByteStringType || it->type == CborTextStringType) {
197         assert(length == (size_t)length);
198         assert((it->flags & CborIteratorFlag_UnknownLength) == 0);
199         it->ptr += length;
200     }
201
202     return preparse_next_value(it);
203 }
204
205 /** \internal
206  *
207  * Decodes the CBOR integer value when it is larger than the 16 bits available
208  * in value->extra. This function requires that value->flags have the
209  * CborIteratorFlag_IntegerValueTooLarge flag set.
210  *
211  * This function is also used to extract single- and double-precision floating
212  * point values (SinglePrecisionFloat == Value32Bit and DoublePrecisionFloat ==
213  * Value64Bit).
214  */
215 uint64_t _cbor_value_decode_int64_internal(const CborValue *value)
216 {
217     assert(value->flags & CborIteratorFlag_IntegerValueTooLarge ||
218            value->type == CborFloatType || value->type == CborDoubleType);
219
220     // since the additional information can only be Value32Bit or Value64Bit,
221     // we just need to test for the one bit those two options differ
222     assert((*value->ptr & SmallValueMask) == Value32Bit || (*value->ptr & SmallValueMask) == Value64Bit);
223     if ((*value->ptr & 1) == (Value32Bit & 1))
224         return get32(value->ptr + 1);
225
226     assert((*value->ptr & SmallValueMask) == Value64Bit);
227     return get64(value->ptr + 1);
228 }
229
230 /**
231  * Initializes the CBOR parser for parsing \a size bytes beginning at \a
232  * buffer. Parsing will use flags set in \a flags. The iterator to the first
233  * element is returned in \a it.
234  *
235  * The \a parser structure needs to remain valid throughout the decoding
236  * process. It is not thread-safe to share one CborParser among multiple
237  * threads iterating at the same time, but the object can be copied so multiple
238  * threads can iterate.
239  *
240  * ### Write how to determine the end pointer
241  * ### Write how to do limited-buffer windowed decoding
242  */
243 CborError cbor_parser_init(const uint8_t *buffer, size_t size, int flags, CborParser *parser, CborValue *it)
244 {
245     memset(parser, 0, sizeof(*parser));
246     parser->end = buffer + size;
247     parser->flags = flags;
248     it->parser = parser;
249     it->ptr = buffer;
250     it->remaining = 1;      // there's one type altogether, usually an array or map
251     return preparse_value(it);
252 }
253
254 /**
255  * Advances the CBOR value \a it by one fixed-size position. Fixed-size types
256  * are: integers, tags, simple types (including boolean, null and undefined
257  * values) and floating point types.
258  *
259  * \sa cbor_value_at_end(), cbor_value_advance(), cbor_value_begin_recurse(), cbor_value_end_recurse()
260  */
261 CborError cbor_value_advance_fixed(CborValue *it)
262 {
263     assert(it->type != CborInvalidType);
264     assert(is_fixed_type(it->type));
265     if (!it->remaining)
266         return CborErrorAdvancePastEOF;
267     return advance_internal(it);
268 }
269
270 static CborError advance_recursive(CborValue *it, int nestingLevel)
271 {
272     if (is_fixed_type(it->type))
273         return advance_internal(it);
274
275     if (!cbor_value_is_container(it)) {
276         size_t len = SIZE_MAX;
277         return _cbor_value_copy_string(it, NULL, &len, it);
278     }
279
280     // map or array
281     if (nestingLevel == CBOR_PARSER_MAX_RECURSIONS)
282         return CborErrorNestingTooDeep;
283
284     CborError err;
285     CborValue recursed;
286     err = cbor_value_enter_container(it, &recursed);
287     if (err)
288         return err;
289     while (!cbor_value_at_end(&recursed)) {
290         err = advance_recursive(&recursed, nestingLevel + 1);
291         if (err)
292             return err;
293     }
294     return cbor_value_leave_container(it, &recursed);
295 }
296
297
298 /**
299  * Advances the CBOR value \a it by one element, skipping over containers.
300  * Unlike cbor_value_advance_fixed(), this function can be called on a CBOR
301  * value of any type. However, if the type is a container (map or array) or a
302  * string with a chunked payload, this function will not run in constant time
303  * and will recurse into itself (it will run on O(n) time for the number of
304  * elements or chunks and will use O(n) memory for the number of nested
305  * containers).
306  *
307  * \sa cbor_value_at_end(), cbor_value_advance_fixed(), cbor_value_begin_recurse(), cbor_value_end_recurse()
308  */
309 CborError cbor_value_advance(CborValue *it)
310 {
311     assert(it->type != CborInvalidType);
312     if (!it->remaining)
313         return CborErrorAdvancePastEOF;
314     return advance_recursive(it, 0);
315 }
316
317 /**
318  * Advances the CBOR value \a it until it no longer points to a tag. If \a it is
319  * already not pointing to a tag, then this function returns it unchanged.
320  *
321  * \sa cbor_value_advance_fixed(), cbor_value_advance()
322  */
323 CborError cbor_value_skip_tag(CborValue *it)
324 {
325     while (cbor_value_is_tag(it)) {
326         CborError err = cbor_value_advance_fixed(it);
327         if (err)
328             return err;
329     }
330     return CborNoError;
331 }
332
333 /**
334  * \fn bool cbor_value_is_container(const CborValue *it)
335  *
336  * Returns true if the \a it value is a container and requires recursion in
337  * order to decode (maps and arrays), false otherwise.
338  */
339
340 /**
341  * Creates a CborValue iterator pointing to the first element of the container
342  * represented by \a it and saves it in \a recursed. The \a it container object
343  * needs to be kept and passed again to cbor_value_leave_container() in order
344  * to continue iterating past this container.
345  *
346  * \sa cbor_value_is_container(), cbor_value_leave_container(), cbor_value_advance()
347  */
348 CborError cbor_value_enter_container(const CborValue *it, CborValue *recursed)
349 {
350     CborError err;
351     assert(cbor_value_is_container(it));
352     *recursed = *it;
353
354     if (it->flags & CborIteratorFlag_UnknownLength) {
355         recursed->remaining = UINT32_MAX;
356         ++recursed->ptr;
357         err = preparse_value(recursed);
358         if (err != CborErrorUnexpectedBreak)
359             return err;
360         // actually, break was expected here
361         // it's just an empty container
362         ++recursed->ptr;
363     } else {
364         uint64_t len;
365         err = extract_number(&recursed->ptr, recursed->parser->end, &len);
366         assert(err == CborNoError);
367
368         recursed->remaining = len;
369         if (recursed->remaining != len || len == UINT32_MAX) {
370             // back track the pointer to indicate where the error occurred
371             recursed->ptr = it->ptr;
372             return CborErrorDataTooLarge;
373         }
374         if (recursed->type == CborMapType) {
375             // maps have keys and values, so we need to multiply by 2
376             if (recursed->remaining > UINT32_MAX / 2) {
377                 // back track the pointer to indicate where the error occurred
378                 recursed->ptr = it->ptr;
379                 return CborErrorDataTooLarge;
380             }
381             recursed->remaining *= 2;
382         }
383         if (len != 0)
384             return preparse_value(recursed);
385     }
386
387     // the case of the empty container
388     recursed->type = CborInvalidType;
389     recursed->remaining = 0;
390     return CborNoError;
391 }
392
393 /**
394  * Updates \a it to point to the next element after the container. The \a
395  * recursed object needs to point to the element obtained either by advancing
396  * the last element of the container (via cbor_value_advance(),
397  * cbor_value_advance_fixed(), a nested cbor_value_leave_container(), or the \c
398  * next pointer from cbor_value_copy_string() or cbor_value_dup_string()).
399  *
400  * \sa cbor_value_enter_container(), cbor_value_at_end()
401  */
402 CborError cbor_value_leave_container(CborValue *it, const CborValue *recursed)
403 {
404     assert(cbor_value_is_container(it));
405     assert(recursed->type == CborInvalidType);
406     it->ptr = recursed->ptr;
407     return preparse_next_value(it);
408 }
409
410 /**
411  * Calculates the length of the string in \a value and stores the result in \a
412  * len. This function is different from cbor_value_get_string_length() in that
413  * it calculates the length even for strings sent in chunks. For that reason,
414  * this function may not run in constant time (it will run in O(n) time on the
415  * number of chunks).
416  *
417  * \note On 32-bit platforms, this function will return error condition of \ref
418  * CborErrorDataTooLarge if the stream indicates a length that is too big to
419  * fit in 32-bit.
420  *
421  * \sa cbor_value_get_string_length(), cbor_value_copy_string(), cbor_value_is_length_known()
422  */
423 CborError cbor_value_calculate_string_length(const CborValue *value, size_t *len)
424 {
425     *len = SIZE_MAX;
426     return _cbor_value_copy_string(value, NULL, len, NULL);
427 }
428
429 /**
430  * \fn CborError cbor_value_dup_text_string(const CborValue *value, char **buffer, size_t *buflen, CborValue *next)
431  *
432  * Allocates memory for the string pointed by \a value and copies it into this
433  * buffer. The pointer to the buffer is stored in \a buffer and the number of
434  * bytes copied is stored in \a len (those variables must not be NULL).
435  *
436  * If \c malloc returns a NULL pointer, this function will return error
437  * condition \ref CborErrorOutOfMemory.
438  *
439  * On success, \c{*buffer} will contain a valid pointer that must be freed by
440  * calling \c{free()}. This is the case even for zero-length strings.
441  *
442  * The \a next pointer, if not null, will be updated to point to the next item
443  * after this string. If \a value points to the last item, then \a next will be
444  * invalid.
445  *
446  * \note This function does not perform UTF-8 validation on the incoming text
447  * string.
448  *
449  * \sa cbor_value_copy_text_string(), cbor_value_dup_byte_string()
450  */
451
452 /**
453  * \fn CborError cbor_value_dup_byte_string(const CborValue *value, uint8_t **buffer, size_t *buflen, CborValue *next)
454  *
455  * Allocates memory for the string pointed by \a value and copies it into this
456  * buffer. The pointer to the buffer is stored in \a buffer and the number of
457  * bytes copied is stored in \a len (those variables must not be NULL).
458  *
459  * If \c malloc returns a NULL pointer, this function will return error
460  * condition \ref CborErrorOutOfMemory.
461  *
462  * On success, \c{*buffer} will contain a valid pointer that must be freed by
463  * calling \c{free()}. This is the case even for zero-length strings.
464  *
465  * The \a next pointer, if not null, will be updated to point to the next item
466  * after this string. If \a value points to the last item, then \a next will be
467  * invalid.
468  *
469  * \sa cbor_value_copy_byte_string(), cbor_value_dup_text_string()
470  */
471 CborError _cbor_value_dup_string(const CborValue *value, void **buffer, size_t *buflen, CborValue *next)
472 {
473     assert(buffer);
474     assert(buflen);
475     *buflen = SIZE_MAX;
476     CborError err = _cbor_value_copy_string(value, NULL, buflen, NULL);
477     if (err)
478         return err;
479
480     ++*buflen;
481     *buffer = malloc(*buflen);
482     if (!*buffer) {
483         // out of memory
484         return CborErrorOutOfMemory;
485     }
486     err = _cbor_value_copy_string(value, *buffer, buflen, next);
487     if (err) {
488         free(*buffer);
489         return err;
490     }
491     return CborNoError;
492 }
493
494 // We return uintptr_t so that we can pass memcpy directly as the iteration
495 // function. The choice is to optimize for memcpy, which is used in the base
496 // parser API (cbor_value_copy_string), while memcmp is used in convenience API
497 // only.
498 typedef uintptr_t (*IterateFunction)(char *, const uint8_t *, size_t);
499
500 static uintptr_t iterate_noop(char *dest, const uint8_t *src, size_t len)
501 {
502     (void)dest;
503     (void)src;
504     (void)len;
505     return true;
506 }
507
508 static uintptr_t iterate_memcmp(char *s1, const uint8_t *s2, size_t len)
509 {
510     return memcmp(s1, (const char *)s2, len) == 0;
511 }
512
513 static CborError iterate_string_chunks(const CborValue *value, char *buffer, size_t *buflen,
514                                        bool *result, CborValue *next, IterateFunction func)
515 {
516     assert(cbor_value_is_byte_string(value) || cbor_value_is_text_string(value));
517
518     size_t total;
519     CborError err;
520     const uint8_t *ptr = value->ptr;
521     if (cbor_value_is_length_known(value)) {
522         // easy case: fixed length
523         err = extract_length(value->parser, &ptr, &total);
524         if (err)
525             return err;
526         if (total > (size_t)(value->parser->end - ptr))
527             return CborErrorUnexpectedEOF;
528         if (total <= *buflen)
529             *result = func(buffer, ptr, total);
530         else
531             *result = false;
532         ptr += total;
533     } else {
534         // chunked
535         ++ptr;
536         total = 0;
537         *result = true;
538         while (true) {
539             size_t chunkLen;
540             size_t newTotal;
541
542             if (ptr == value->parser->end)
543                 return CborErrorUnexpectedEOF;
544
545             if (*ptr == (uint8_t)BreakByte) {
546                 ++ptr;
547                 break;
548             }
549
550             // is this the right type?
551             if ((*ptr & MajorTypeMask) != value->type)
552                 return CborErrorIllegalType;
553
554             err = extract_length(value->parser, &ptr, &chunkLen);
555             if (err)
556                 return err;
557
558             if (unlikely(add_check_overflow(total, chunkLen, &newTotal)))
559                 return CborErrorDataTooLarge;
560
561             if (chunkLen > (size_t)(value->parser->end - ptr))
562                 return CborErrorUnexpectedEOF;
563
564             if (*result && *buflen >= newTotal)
565                 *result = func(buffer + total, ptr, chunkLen);
566             else
567                 *result = false;
568
569             ptr += chunkLen;
570             total = newTotal;
571         }
572     }
573
574     // is there enough room for the ending NUL byte?
575     if (*result && *buflen > total)
576         *result = func(buffer + total, (const uint8_t *)"", 1);
577     *buflen = total;
578
579     if (next) {
580         *next = *value;
581         next->ptr = ptr;
582         return preparse_next_value(next);
583     }
584     return CborNoError;
585 }
586
587 /**
588  * \fn CborError cbor_value_copy_text_string(const CborValue *value, char *buffer, size_t *buflen, CborValue *next)
589  *
590  * Copies the string pointed by \a value into the buffer provided at \a buffer
591  * of \a buflen bytes. If \a buffer is a NULL pointer, this function will not
592  * copy anything and will only update the \a next value.
593  *
594  * If the provided buffer length was too small, this function returns an error
595  * condition of \ref CborErrorOutOfMemory. If you need to calculate the length
596  * of the string in order to preallocate a buffer, use
597  * cbor_value_calculate_string_length().
598  *
599  * On success, this function sets the number of bytes copied to \c{*buflen}. If
600  * the buffer is large enough, this function will insert a null byte after the
601  * last copied byte, to facilitate manipulation of text strings. That byte is
602  * not included in the returned value of \c{*buflen}.
603  *
604  * The \a next pointer, if not null, will be updated to point to the next item
605  * after this string. If \a value points to the last item, then \a next will be
606  * invalid.
607  *
608  * \note This function does not perform UTF-8 validation on the incoming text
609  * string.
610  *
611  * \sa cbor_value_dup_text_string(), cbor_value_copy_byte_string(), cbor_value_get_string_length(), cbor_value_calculate_string_length()
612  */
613
614 /**
615  * \fn CborError cbor_value_copy_byte_string(const CborValue *value, uint8_t *buffer, size_t *buflen, CborValue *next)
616  *
617  * Copies the string pointed by \a value into the buffer provided at \a buffer
618  * of \a buflen bytes. If \a buffer is a NULL pointer, this function will not
619  * copy anything and will only update the \a next value.
620  *
621  * If the provided buffer length was too small, this function returns an error
622  * condition of \ref CborErrorOutOfMemory. If you need to calculate the length
623  * of the string in order to preallocate a buffer, use
624  * cbor_value_calculate_string_length().
625  *
626  * On success, this function sets the number of bytes copied to \c{*buflen}. If
627  * the buffer is large enough, this function will insert a null byte after the
628  * last copied byte, to facilitate manipulation of null-terminated strings.
629  * That byte is not included in the returned value of \c{*buflen}.
630  *
631  * The \a next pointer, if not null, will be updated to point to the next item
632  * after this string. If \a value points to the last item, then \a next will be
633  * invalid.
634  *
635  * \sa cbor_value_dup_text_string(), cbor_value_copy_text_string(), cbor_value_get_string_length(), cbor_value_calculate_string_length()
636  */
637
638 CborError _cbor_value_copy_string(const CborValue *value, void *buffer,
639                                  size_t *buflen, CborValue *next)
640 {
641     bool copied_all;
642     CborError err = iterate_string_chunks(value, (char*)buffer, buflen, &copied_all, next,
643                                           buffer ? (IterateFunction)memcpy : iterate_noop);
644     return err ? err :
645                  copied_all ? CborNoError : CborErrorOutOfMemory;
646 }
647
648 /**
649  * Compares the entry \a value with the string \a string and store the result
650  * in \a result. If the value is different from \a string or if it is not a
651  * text string, \a result will contain \c false.
652  *
653  * The entry at \a value may be a tagged string. If \a is not a string or a
654  * tagged string, the comparison result will be false.
655  */
656 CborError cbor_value_text_string_equals(const CborValue *value, const char *string, bool *result)
657 {
658     CborValue copy = *value;
659     CborError err = cbor_value_skip_tag(&copy);
660     if (err)
661         return err;
662     if (!cbor_value_is_text_string(&copy)) {
663         *result = false;
664         return CborNoError;
665     }
666
667     size_t len = strlen(string);
668     return iterate_string_chunks(&copy, CONST_CAST(char *, string), &len, result, NULL, iterate_memcmp);
669 }
670
671 /**
672  * Attempts to find the value in map \a map that corresponds to the text string
673  * entry \a string. If the item is found, it is stored in \a result. If no item
674  * is found matching the key, then \a result will contain an element of type
675  * \ref CborInvalidType.
676  *
677  * \note This function may be expensive to execute.
678  */
679 CborError cbor_value_map_find_value(const CborValue *map, const char *string, CborValue *element)
680 {
681     assert(cbor_value_is_map(map));
682     size_t len = strlen(string);
683     CborError err = cbor_value_enter_container(map, element);
684     if (err)
685         goto error;
686
687     while (!cbor_value_at_end(element)) {
688         // find the non-tag so we can compare
689         err = cbor_value_skip_tag(element);
690         if (err)
691             goto error;
692         if (cbor_value_is_text_string(element)) {
693             bool equals;
694             size_t dummyLen = len;
695             err = iterate_string_chunks(element, CONST_CAST(char *, string), &dummyLen,
696                                         &equals, element, iterate_memcmp);
697             if (err)
698                 goto error;
699             if (equals)
700                 return preparse_value(element);
701         } else {
702             // skip this key
703             err = cbor_value_advance(element);
704             if (err)
705                 goto error;
706         }
707
708         // skip this value
709         err = cbor_value_skip_tag(element);
710         if (err)
711             goto error;
712         err = cbor_value_advance(element);
713         if (err)
714             goto error;
715     }
716
717     // not found
718     element->type = CborInvalidType;
719     return CborNoError;
720
721 error:
722     element->type = CborInvalidType;
723     return err;
724 }
725
726 /**
727  * Extracts a half-precision floating point from \a value and stores it in \a
728  * result.
729  */
730 CborError cbor_value_get_half_float(const CborValue *value, void *result)
731 {
732     assert(value->type == CborHalfFloatType);
733
734     // size has been computed already
735     uint16_t v = get16(value->ptr + 1);
736     memcpy(result, &v, sizeof(v));
737     return CborNoError;
738 }