1 /****************************************************************************
3 ** Copyright (C) 2015 Intel Corporation
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:
12 ** The above copyright notice and this permission notice shall be included in
13 ** all copies or substantial portions of the Software.
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
23 ****************************************************************************/
27 #include "cborconstants_p.h"
28 #include "compilersupport_p.h"
29 #include "extract_number_p.h"
35 #include "assert_p.h" /* Always include last */
37 #ifndef CBOR_PARSER_MAX_RECURSIONS
38 # define CBOR_PARSER_MAX_RECURSIONS 1024
43 * This type contains one value parsed from the CBOR stream.
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().
50 * In C++ and C11 modes, you can additionally use the cbor_value_get_integer()
51 * and cbor_value_get_floating_point() generic functions.
54 * Implementation details: the CborValue contains these fields:
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
64 static CborError extract_length(const CborParser *parser, const uint8_t **ptr, size_t *len)
67 CborError err = extract_number(ptr, parser->end, &v);
75 return CborErrorDataTooLarge;
79 static bool is_fixed_type(uint8_t type)
81 return type != CborTextStringType && type != CborByteStringType && type != CborArrayType &&
85 static CborError preparse_value(CborValue *it)
87 const CborParser *parser = it->parser;
88 it->type = CborInvalidType;
91 if (it->ptr == parser->end)
92 return CborErrorUnexpectedEOF;
94 uint8_t descriptor = *it->ptr;
95 uint8_t type = descriptor & MajorTypeMask;
98 it->extra = (descriptor &= SmallValueMask);
100 if (descriptor > Value64Bit) {
101 if (unlikely(descriptor != IndefiniteLength))
102 return type == CborSimpleType ? CborErrorUnknownType : CborErrorIllegalNumber;
103 if (likely(!is_fixed_type(type))) {
105 it->flags |= CborIteratorFlag_UnknownLength;
109 return type == CborSimpleType ? CborErrorUnexpectedBreak : CborErrorIllegalNumber;
112 size_t bytesNeeded = descriptor < Value8Bit ? 0 : (1 << (descriptor - Value8Bit));
113 if (bytesNeeded + 1 > (size_t)(parser->end - it->ptr))
114 return CborErrorUnexpectedEOF;
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) {
124 it->type = CborBooleanType;
127 case SinglePrecisionFloat:
128 case DoublePrecisionFloat:
129 it->flags |= CborIteratorFlag_IntegerValueTooLarge;
134 case HalfPrecisionFloat:
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;
152 assert(false); // these conditions can't be reached
153 return CborErrorUnexpectedBreak;
158 // try to decode up to 16 bits
159 if (descriptor < Value8Bit)
162 if (descriptor == Value8Bit)
163 it->extra = (uint8_t)it->ptr[1];
164 else if (descriptor == Value16Bit)
165 it->extra = get16(it->ptr + 1);
167 it->flags |= CborIteratorFlag_IntegerValueTooLarge; // Value32Bit or Value64Bit
171 static CborError preparse_next_value(CborValue *it)
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;
179 } else if (it->remaining == UINT32_MAX && it->ptr != it->parser->end && *it->ptr == (uint8_t)BreakByte) {
180 // end of map or array
182 it->type = CborInvalidType;
187 return preparse_value(it);
190 static CborError advance_internal(CborValue *it)
193 CborError err = extract_number(&it->ptr, it->parser->end, &length);
194 assert(err == CborNoError);
196 if (it->type == CborByteStringType || it->type == CborTextStringType) {
197 assert(length == (size_t)length);
198 assert((it->flags & CborIteratorFlag_UnknownLength) == 0);
202 return preparse_next_value(it);
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.
211 * This function is also used to extract single- and double-precision floating
212 * point values (SinglePrecisionFloat == Value32Bit and DoublePrecisionFloat ==
215 uint64_t _cbor_value_decode_int64_internal(const CborValue *value)
217 assert(value->flags & CborIteratorFlag_IntegerValueTooLarge ||
218 value->type == CborFloatType || value->type == CborDoubleType);
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);
226 assert((*value->ptr & SmallValueMask) == Value64Bit);
227 return get64(value->ptr + 1);
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.
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.
240 * ### Write how to determine the end pointer
241 * ### Write how to do limited-buffer windowed decoding
243 CborError cbor_parser_init(const uint8_t *buffer, size_t size, int flags, CborParser *parser, CborValue *it)
245 memset(parser, 0, sizeof(*parser));
246 parser->end = buffer + size;
247 parser->flags = flags;
250 it->remaining = 1; // there's one type altogether, usually an array or map
251 return preparse_value(it);
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.
259 * \sa cbor_value_at_end(), cbor_value_advance(), cbor_value_begin_recurse(), cbor_value_end_recurse()
261 CborError cbor_value_advance_fixed(CborValue *it)
263 assert(it->type != CborInvalidType);
264 assert(is_fixed_type(it->type));
266 return CborErrorAdvancePastEOF;
267 return advance_internal(it);
270 static CborError advance_recursive(CborValue *it, int nestingLevel)
272 if (is_fixed_type(it->type))
273 return advance_internal(it);
275 if (!cbor_value_is_container(it)) {
276 size_t len = SIZE_MAX;
277 return _cbor_value_copy_string(it, NULL, &len, it);
281 if (nestingLevel == CBOR_PARSER_MAX_RECURSIONS)
282 return CborErrorNestingTooDeep;
286 err = cbor_value_enter_container(it, &recursed);
289 while (!cbor_value_at_end(&recursed)) {
290 err = advance_recursive(&recursed, nestingLevel + 1);
294 return cbor_value_leave_container(it, &recursed);
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
307 * \sa cbor_value_at_end(), cbor_value_advance_fixed(), cbor_value_begin_recurse(), cbor_value_end_recurse()
309 CborError cbor_value_advance(CborValue *it)
311 assert(it->type != CborInvalidType);
313 return CborErrorAdvancePastEOF;
314 return advance_recursive(it, 0);
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.
321 * \sa cbor_value_advance_fixed(), cbor_value_advance()
323 CborError cbor_value_skip_tag(CborValue *it)
325 while (cbor_value_is_tag(it)) {
326 CborError err = cbor_value_advance_fixed(it);
334 * \fn bool cbor_value_is_container(const CborValue *it)
336 * Returns true if the \a it value is a container and requires recursion in
337 * order to decode (maps and arrays), false otherwise.
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.
346 * \sa cbor_value_is_container(), cbor_value_leave_container(), cbor_value_advance()
348 CborError cbor_value_enter_container(const CborValue *it, CborValue *recursed)
351 assert(cbor_value_is_container(it));
354 if (it->flags & CborIteratorFlag_UnknownLength) {
355 recursed->remaining = UINT32_MAX;
357 err = preparse_value(recursed);
358 if (err != CborErrorUnexpectedBreak)
360 // actually, break was expected here
361 // it's just an empty container
365 err = extract_number(&recursed->ptr, recursed->parser->end, &len);
366 assert(err == CborNoError);
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;
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;
381 recursed->remaining *= 2;
384 return preparse_value(recursed);
387 // the case of the empty container
388 recursed->type = CborInvalidType;
389 recursed->remaining = 0;
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()).
400 * \sa cbor_value_enter_container(), cbor_value_at_end()
402 CborError cbor_value_leave_container(CborValue *it, const CborValue *recursed)
404 assert(cbor_value_is_container(it));
405 assert(recursed->type == CborInvalidType);
406 it->ptr = recursed->ptr;
407 return preparse_next_value(it);
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
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
421 * \sa cbor_value_get_string_length(), cbor_value_copy_string(), cbor_value_is_length_known()
423 CborError cbor_value_calculate_string_length(const CborValue *value, size_t *len)
426 return _cbor_value_copy_string(value, NULL, len, NULL);
430 * \fn CborError cbor_value_dup_text_string(const CborValue *value, char **buffer, size_t *buflen, CborValue *next)
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).
436 * If \c malloc returns a NULL pointer, this function will return error
437 * condition \ref CborErrorOutOfMemory.
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.
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
446 * \note This function does not perform UTF-8 validation on the incoming text
449 * \sa cbor_value_copy_text_string(), cbor_value_dup_byte_string()
453 * \fn CborError cbor_value_dup_byte_string(const CborValue *value, uint8_t **buffer, size_t *buflen, CborValue *next)
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).
459 * If \c malloc returns a NULL pointer, this function will return error
460 * condition \ref CborErrorOutOfMemory.
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.
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
469 * \sa cbor_value_copy_byte_string(), cbor_value_dup_text_string()
471 CborError _cbor_value_dup_string(const CborValue *value, void **buffer, size_t *buflen, CborValue *next)
476 CborError err = _cbor_value_copy_string(value, NULL, buflen, NULL);
481 *buffer = malloc(*buflen);
484 return CborErrorOutOfMemory;
486 err = _cbor_value_copy_string(value, *buffer, buflen, next);
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
498 typedef uintptr_t (*IterateFunction)(char *, const uint8_t *, size_t);
500 static uintptr_t iterate_noop(char *dest, const uint8_t *src, size_t len)
508 static uintptr_t iterate_memcmp(char *s1, const uint8_t *s2, size_t len)
510 return memcmp(s1, (const char *)s2, len) == 0;
513 static CborError iterate_string_chunks(const CborValue *value, char *buffer, size_t *buflen,
514 bool *result, CborValue *next, IterateFunction func)
516 assert(cbor_value_is_byte_string(value) || cbor_value_is_text_string(value));
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);
526 if (total > (size_t)(value->parser->end - ptr))
527 return CborErrorUnexpectedEOF;
528 if (total <= *buflen)
529 *result = func(buffer, ptr, total);
542 if (ptr == value->parser->end)
543 return CborErrorUnexpectedEOF;
545 if (*ptr == (uint8_t)BreakByte) {
550 // is this the right type?
551 if ((*ptr & MajorTypeMask) != value->type)
552 return CborErrorIllegalType;
554 err = extract_length(value->parser, &ptr, &chunkLen);
558 if (unlikely(add_check_overflow(total, chunkLen, &newTotal)))
559 return CborErrorDataTooLarge;
561 if (chunkLen > (size_t)(value->parser->end - ptr))
562 return CborErrorUnexpectedEOF;
564 if (*result && *buflen >= newTotal)
565 *result = func(buffer + total, ptr, chunkLen);
574 // is there enough room for the ending NUL byte?
575 if (*result && *buflen > total)
576 *result = func(buffer + total, (const uint8_t *)"", 1);
582 return preparse_next_value(next);
588 * \fn CborError cbor_value_copy_text_string(const CborValue *value, char *buffer, size_t *buflen, CborValue *next)
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.
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().
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}.
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
608 * \note This function does not perform UTF-8 validation on the incoming text
611 * \sa cbor_value_dup_text_string(), cbor_value_copy_byte_string(), cbor_value_get_string_length(), cbor_value_calculate_string_length()
615 * \fn CborError cbor_value_copy_byte_string(const CborValue *value, uint8_t *buffer, size_t *buflen, CborValue *next)
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.
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().
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}.
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
635 * \sa cbor_value_dup_text_string(), cbor_value_copy_text_string(), cbor_value_get_string_length(), cbor_value_calculate_string_length()
638 CborError _cbor_value_copy_string(const CborValue *value, void *buffer,
639 size_t *buflen, CborValue *next)
642 CborError err = iterate_string_chunks(value, (char*)buffer, buflen, &copied_all, next,
643 buffer ? (IterateFunction)memcpy : iterate_noop);
645 copied_all ? CborNoError : CborErrorOutOfMemory;
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.
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.
656 CborError cbor_value_text_string_equals(const CborValue *value, const char *string, bool *result)
658 CborValue copy = *value;
659 CborError err = cbor_value_skip_tag(©);
662 if (!cbor_value_is_text_string(©)) {
667 size_t len = strlen(string);
668 return iterate_string_chunks(©, CONST_CAST(char *, string), &len, result, NULL, iterate_memcmp);
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.
677 * \note This function may be expensive to execute.
679 CborError cbor_value_map_find_value(const CborValue *map, const char *string, CborValue *element)
681 assert(cbor_value_is_map(map));
682 size_t len = strlen(string);
683 CborError err = cbor_value_enter_container(map, element);
687 while (!cbor_value_at_end(element)) {
688 // find the non-tag so we can compare
689 err = cbor_value_skip_tag(element);
692 if (cbor_value_is_text_string(element)) {
694 size_t dummyLen = len;
695 err = iterate_string_chunks(element, CONST_CAST(char *, string), &dummyLen,
696 &equals, element, iterate_memcmp);
700 return preparse_value(element);
703 err = cbor_value_advance(element);
709 err = cbor_value_skip_tag(element);
712 err = cbor_value_advance(element);
718 element->type = CborInvalidType;
722 element->type = CborInvalidType;
727 * Extracts a half-precision floating point from \a value and stores it in \a
730 CborError cbor_value_get_half_float(const CborValue *value, void *result)
732 assert(value->type == CborHalfFloatType);
734 // size has been computed already
735 uint16_t v = get16(value->ptr + 1);
736 memcpy(result, &v, sizeof(v));