]>
Commit | Line | Data |
---|---|---|
0bb51450 OM |
1 | /**************************************************************************** |
2 | ** | |
3 | ** Copyright (C) 2017 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 | #ifndef _BSD_SOURCE | |
26 | #define _BSD_SOURCE 1 | |
27 | #endif | |
28 | #ifndef _DEFAULT_SOURCE | |
29 | #define _DEFAULT_SOURCE 1 | |
30 | #endif | |
31 | #ifndef __STDC_LIMIT_MACROS | |
32 | # define __STDC_LIMIT_MACROS 1 | |
33 | #endif | |
34 | ||
35 | #include "cbor.h" | |
36 | #include "cborinternal_p.h" | |
37 | #include "compilersupport_p.h" | |
38 | ||
39 | #include <string.h> | |
40 | ||
41 | /** | |
42 | * \defgroup CborParsing Parsing CBOR streams | |
43 | * \brief Group of functions used to parse CBOR streams. | |
44 | * | |
45 | * TinyCBOR provides functions for pull-based stream parsing of a CBOR-encoded | |
46 | * payload. The main data type for the parsing is a CborValue, which behaves | |
47 | * like an iterator and can be used to extract the encoded data. It is first | |
48 | * initialized with a call to cbor_parser_init() and is usually used to extract | |
49 | * exactly one item, most often an array or map. | |
50 | * | |
51 | * Nested CborValue objects can be parsed using cbor_value_enter_container(). | |
52 | * Each call to cbor_value_enter_container() must be matched by a call to | |
53 | * cbor_value_leave_container(), with the exact same parameters. | |
54 | * | |
55 | * The example below initializes a CborParser object, begins the parsing with a | |
56 | * CborValue and decodes a single integer: | |
57 | * | |
58 | * \code | |
59 | * int extract_int(const uint8_t *buffer, size_t len) | |
60 | * { | |
61 | * CborParser parser; | |
62 | * CborValue value; | |
63 | * int result; | |
64 | * cbor_parser_init(buffer, len, 0, &parser, &value); | |
65 | * cbor_value_get_int(&value, &result); | |
66 | * return result; | |
67 | * } | |
68 | * \endcode | |
69 | * | |
70 | * The code above does no error checking, which means it assumes the data comes | |
71 | * from a source trusted to send one properly-encoded integer. The following | |
72 | * example does the exact same operation, but includes error checking and | |
73 | * returns 0 on parsing failure: | |
74 | * | |
75 | * \code | |
76 | * int extract_int(const uint8_t *buffer, size_t len) | |
77 | * { | |
78 | * CborParser parser; | |
79 | * CborValue value; | |
80 | * int result; | |
81 | * if (cbor_parser_init(buffer, len, 0, &parser, &value) != CborNoError) | |
82 | * return 0; | |
83 | * if (!cbor_value_is_integer(&value) || | |
84 | * cbor_value_get_int(&value, &result) != CborNoError) | |
85 | * return 0; | |
86 | * return result; | |
87 | * } | |
88 | * \endcode | |
89 | * | |
90 | * Note, in the example above, that one can't distinguish a parsing failure | |
91 | * from an encoded value of zero. Reporting a parsing error is left as an | |
92 | * exercise to the reader. | |
93 | * | |
94 | * The code above does not execute a range-check either: it is possible that | |
95 | * the value decoded from the CBOR stream encodes a number larger than what can | |
96 | * be represented in a variable of type \c{int}. If detecting that case is | |
97 | * important, the code should call cbor_value_get_int_checked() instead. | |
98 | * | |
99 | * <h3 class="groupheader">Memory and parsing constraints</h3> | |
100 | * | |
101 | * TinyCBOR is designed to run with little memory and with minimal overhead. | |
102 | * Except where otherwise noted, the parser functions always run on constant | |
103 | * time (O(1)), do not recurse and never allocate memory (thus, stack usage is | |
104 | * bounded and is O(1)). | |
105 | * | |
106 | * <h3 class="groupheader">Error handling and preconditions</h3> | |
107 | * | |
108 | * All functions operating on a CborValue return a CborError condition, with | |
109 | * CborNoError standing for the normal situation in which no parsing error | |
110 | * occurred. All functions may return parsing errors in case the stream cannot | |
111 | * be decoded properly, be it due to corrupted data or due to reaching the end | |
112 | * of the input buffer. | |
113 | * | |
114 | * Error conditions must not be ignored. All decoder functions have undefined | |
115 | * behavior if called after an error has been reported, and may crash. | |
116 | * | |
117 | * Some functions are also documented to have preconditions, like | |
118 | * cbor_value_get_int() requiring that the input be an integral value. | |
119 | * Violation of preconditions also results in undefined behavior and the | |
120 | * program may crash. | |
121 | */ | |
122 | ||
123 | /** | |
124 | * \addtogroup CborParsing | |
125 | * @{ | |
126 | */ | |
127 | ||
128 | /** | |
129 | * \struct CborValue | |
130 | * | |
131 | * This type contains one value parsed from the CBOR stream. Each CborValue | |
132 | * behaves as an iterator in a StAX-style parser. | |
133 | * | |
134 | * \if privatedocs | |
135 | * Implementation details: the CborValue contains these fields: | |
136 | * \list | |
137 | * \li ptr: pointer to the actual data | |
138 | * \li flags: flags from the decoder | |
139 | * \li extra: partially decoded integer value (0, 1 or 2 bytes) | |
140 | * \li remaining: remaining items in this collection after this item or UINT32_MAX if length is unknown | |
141 | * \endlist | |
142 | * \endif | |
143 | */ | |
144 | ||
145 | static inline uint16_t get16(const uint8_t *ptr) | |
146 | { | |
147 | uint16_t result; | |
148 | memcpy(&result, ptr, sizeof(result)); | |
149 | return cbor_ntohs(result); | |
150 | } | |
151 | ||
152 | static inline uint32_t get32(const uint8_t *ptr) | |
153 | { | |
154 | uint32_t result; | |
155 | memcpy(&result, ptr, sizeof(result)); | |
156 | return cbor_ntohl(result); | |
157 | } | |
158 | ||
159 | static inline uint64_t get64(const uint8_t *ptr) | |
160 | { | |
161 | uint64_t result; | |
162 | memcpy(&result, ptr, sizeof(result)); | |
163 | return cbor_ntohll(result); | |
164 | } | |
165 | ||
166 | CborError CBOR_INTERNAL_API_CC _cbor_value_extract_number(const uint8_t **ptr, const uint8_t *end, uint64_t *len) | |
167 | { | |
168 | size_t bytesNeeded; | |
169 | uint8_t additional_information = **ptr & SmallValueMask; | |
170 | ++*ptr; | |
171 | if (additional_information < Value8Bit) { | |
172 | *len = additional_information; | |
173 | return CborNoError; | |
174 | } | |
175 | if (unlikely(additional_information > Value64Bit)) | |
176 | return CborErrorIllegalNumber; | |
177 | ||
178 | bytesNeeded = (size_t)(1 << (additional_information - Value8Bit)); | |
179 | if (unlikely(bytesNeeded > (size_t)(end - *ptr))) { | |
180 | return CborErrorUnexpectedEOF; | |
181 | } else if (bytesNeeded == 1) { | |
182 | *len = (uint8_t)(*ptr)[0]; | |
183 | } else if (bytesNeeded == 2) { | |
184 | *len = get16(*ptr); | |
185 | } else if (bytesNeeded == 4) { | |
186 | *len = get32(*ptr); | |
187 | } else { | |
188 | *len = get64(*ptr); | |
189 | } | |
190 | *ptr += bytesNeeded; | |
191 | return CborNoError; | |
192 | } | |
193 | ||
194 | static CborError extract_length(const CborParser *parser, const uint8_t **ptr, size_t *len) | |
195 | { | |
196 | uint64_t v; | |
197 | CborError err = _cbor_value_extract_number(ptr, parser->end, &v); | |
198 | if (err) { | |
199 | *len = 0; | |
200 | return err; | |
201 | } | |
202 | ||
203 | *len = (size_t)v; | |
204 | if (v != *len) | |
205 | return CborErrorDataTooLarge; | |
206 | return CborNoError; | |
207 | } | |
208 | ||
209 | static bool is_fixed_type(uint8_t type) | |
210 | { | |
211 | return type != CborTextStringType && type != CborByteStringType && type != CborArrayType && | |
212 | type != CborMapType; | |
213 | } | |
214 | ||
215 | static CborError preparse_value(CborValue *it) | |
216 | { | |
217 | const CborParser *parser = it->parser; | |
218 | it->type = CborInvalidType; | |
219 | ||
220 | /* are we at the end? */ | |
221 | if (it->ptr == parser->end) | |
222 | return CborErrorUnexpectedEOF; | |
223 | ||
224 | uint8_t descriptor = *it->ptr; | |
225 | uint8_t type = descriptor & MajorTypeMask; | |
226 | it->type = type; | |
227 | it->flags = 0; | |
228 | it->extra = (descriptor &= SmallValueMask); | |
229 | ||
230 | if (descriptor > Value64Bit) { | |
231 | if (unlikely(descriptor != IndefiniteLength)) | |
232 | return type == CborSimpleType ? CborErrorUnknownType : CborErrorIllegalNumber; | |
233 | if (likely(!is_fixed_type(type))) { | |
234 | /* special case */ | |
235 | it->flags |= CborIteratorFlag_UnknownLength; | |
236 | it->type = type; | |
237 | return CborNoError; | |
238 | } | |
239 | return type == CborSimpleType ? CborErrorUnexpectedBreak : CborErrorIllegalNumber; | |
240 | } | |
241 | ||
242 | size_t bytesNeeded = descriptor < Value8Bit ? 0 : (1 << (descriptor - Value8Bit)); | |
243 | if (bytesNeeded + 1 > (size_t)(parser->end - it->ptr)) | |
244 | return CborErrorUnexpectedEOF; | |
245 | ||
246 | uint8_t majortype = type >> MajorTypeShift; | |
247 | if (majortype == NegativeIntegerType) { | |
248 | it->flags |= CborIteratorFlag_NegativeInteger; | |
249 | it->type = CborIntegerType; | |
250 | } else if (majortype == SimpleTypesType) { | |
251 | switch (descriptor) { | |
252 | case FalseValue: | |
253 | it->extra = false; | |
254 | it->type = CborBooleanType; | |
255 | break; | |
256 | ||
257 | case SinglePrecisionFloat: | |
258 | case DoublePrecisionFloat: | |
259 | it->flags |= CborIteratorFlag_IntegerValueTooLarge; | |
260 | /* fall through */ | |
261 | case TrueValue: | |
262 | case NullValue: | |
263 | case UndefinedValue: | |
264 | case HalfPrecisionFloat: | |
265 | it->type = *it->ptr; | |
266 | break; | |
267 | ||
268 | case SimpleTypeInNextByte: | |
269 | it->extra = (uint8_t)it->ptr[1]; | |
270 | #ifndef CBOR_PARSER_NO_STRICT_CHECKS | |
271 | if (unlikely(it->extra < 32)) { | |
272 | it->type = CborInvalidType; | |
273 | return CborErrorIllegalSimpleType; | |
274 | } | |
275 | #endif | |
276 | break; | |
277 | ||
278 | case 28: | |
279 | case 29: | |
280 | case 30: | |
281 | case Break: | |
282 | cbor_assert(false); /* these conditions can't be reached */ | |
283 | return CborErrorUnexpectedBreak; | |
284 | } | |
285 | return CborNoError; | |
286 | } | |
287 | ||
288 | /* try to decode up to 16 bits */ | |
289 | if (descriptor < Value8Bit) | |
290 | return CborNoError; | |
291 | ||
292 | if (descriptor == Value8Bit) | |
293 | it->extra = (uint8_t)it->ptr[1]; | |
294 | else if (descriptor == Value16Bit) | |
295 | it->extra = get16(it->ptr + 1); | |
296 | else | |
297 | it->flags |= CborIteratorFlag_IntegerValueTooLarge; /* Value32Bit or Value64Bit */ | |
298 | return CborNoError; | |
299 | } | |
300 | ||
301 | static CborError preparse_next_value_nodecrement(CborValue *it) | |
302 | { | |
303 | if (it->remaining == UINT32_MAX && it->ptr != it->parser->end && *it->ptr == (uint8_t)BreakByte) { | |
304 | /* end of map or array */ | |
305 | ++it->ptr; | |
306 | it->type = CborInvalidType; | |
307 | it->remaining = 0; | |
308 | return CborNoError; | |
309 | } | |
310 | ||
311 | return preparse_value(it); | |
312 | } | |
313 | ||
314 | static CborError preparse_next_value(CborValue *it) | |
315 | { | |
316 | if (it->remaining != UINT32_MAX) { | |
317 | /* don't decrement the item count if the current item is tag: they don't count */ | |
318 | if (it->type != CborTagType && --it->remaining == 0) { | |
319 | it->type = CborInvalidType; | |
320 | return CborNoError; | |
321 | } | |
322 | } | |
323 | return preparse_next_value_nodecrement(it); | |
324 | } | |
325 | ||
326 | static CborError advance_internal(CborValue *it) | |
327 | { | |
328 | uint64_t length; | |
329 | CborError err = _cbor_value_extract_number(&it->ptr, it->parser->end, &length); | |
330 | cbor_assert(err == CborNoError); | |
331 | ||
332 | if (it->type == CborByteStringType || it->type == CborTextStringType) { | |
333 | cbor_assert(length == (size_t)length); | |
334 | cbor_assert((it->flags & CborIteratorFlag_UnknownLength) == 0); | |
335 | it->ptr += length; | |
336 | } | |
337 | ||
338 | return preparse_next_value(it); | |
339 | } | |
340 | ||
341 | /** \internal | |
342 | * | |
343 | * Decodes the CBOR integer value when it is larger than the 16 bits available | |
344 | * in value->extra. This function requires that value->flags have the | |
345 | * CborIteratorFlag_IntegerValueTooLarge flag set. | |
346 | * | |
347 | * This function is also used to extract single- and double-precision floating | |
348 | * point values (SinglePrecisionFloat == Value32Bit and DoublePrecisionFloat == | |
349 | * Value64Bit). | |
350 | */ | |
351 | uint64_t _cbor_value_decode_int64_internal(const CborValue *value) | |
352 | { | |
353 | cbor_assert(value->flags & CborIteratorFlag_IntegerValueTooLarge || | |
354 | value->type == CborFloatType || value->type == CborDoubleType); | |
355 | ||
356 | /* since the additional information can only be Value32Bit or Value64Bit, | |
357 | * we just need to test for the one bit those two options differ */ | |
358 | cbor_assert((*value->ptr & SmallValueMask) == Value32Bit || (*value->ptr & SmallValueMask) == Value64Bit); | |
359 | if ((*value->ptr & 1) == (Value32Bit & 1)) | |
360 | return get32(value->ptr + 1); | |
361 | ||
362 | cbor_assert((*value->ptr & SmallValueMask) == Value64Bit); | |
363 | return get64(value->ptr + 1); | |
364 | } | |
365 | ||
366 | /** | |
367 | * Initializes the CBOR parser for parsing \a size bytes beginning at \a | |
368 | * buffer. Parsing will use flags set in \a flags. The iterator to the first | |
369 | * element is returned in \a it. | |
370 | * | |
371 | * The \a parser structure needs to remain valid throughout the decoding | |
372 | * process. It is not thread-safe to share one CborParser among multiple | |
373 | * threads iterating at the same time, but the object can be copied so multiple | |
374 | * threads can iterate. | |
375 | */ | |
376 | CborError cbor_parser_init(const uint8_t *buffer, size_t size, uint32_t flags, CborParser *parser, CborValue *it) | |
377 | { | |
378 | memset(parser, 0, sizeof(*parser)); | |
379 | parser->end = buffer + size; | |
380 | parser->flags = flags; | |
381 | it->parser = parser; | |
382 | it->ptr = buffer; | |
383 | it->remaining = 1; /* there's one type altogether, usually an array or map */ | |
384 | return preparse_value(it); | |
385 | } | |
386 | ||
387 | /** | |
388 | * \fn bool cbor_value_at_end(const CborValue *it) | |
389 | * | |
390 | * Returns true if \a it has reached the end of the iteration, usually when | |
391 | * advancing after the last item in an array or map. | |
392 | * | |
393 | * In the case of the outermost CborValue object, this function returns true | |
394 | * after decoding a single element. A pointer to the first byte of the | |
395 | * remaining data (if any) can be obtained with cbor_value_get_next_byte(). | |
396 | * | |
397 | * \sa cbor_value_advance(), cbor_value_is_valid(), cbor_value_get_next_byte() | |
398 | */ | |
399 | ||
400 | /** | |
401 | * \fn const uint8_t *cbor_value_get_next_byte(const CborValue *it) | |
402 | * | |
403 | * Returns a pointer to the next byte that would be decoded if this CborValue | |
404 | * object were advanced. | |
405 | * | |
406 | * This function is useful if cbor_value_at_end() returns true for the | |
407 | * outermost CborValue: the pointer returned is the first byte of the data | |
408 | * remaining in the buffer, if any. Code can decide whether to begin decoding a | |
409 | * new CBOR data stream from this point, or parse some other data appended to | |
410 | * the same buffer. | |
411 | * | |
412 | * This function may be used even after a parsing error. If that occurred, | |
413 | * then this function returns a pointer to where the parsing error occurred. | |
414 | * Note that the error recovery is not precise and the pointer may not indicate | |
415 | * the exact byte containing bad data. | |
416 | * | |
417 | * \sa cbor_value_at_end() | |
418 | */ | |
419 | ||
420 | /** | |
421 | * \fn bool cbor_value_is_valid(const CborValue *it) | |
422 | * | |
423 | * Returns true if the iterator \a it contains a valid value. Invalid iterators | |
424 | * happen when iteration reaches the end of a container (see \ref | |
425 | * cbor_value_at_end()) or when a search function resulted in no matches. | |
426 | * | |
427 | * \sa cbor_value_advance(), cbor_value_at_end(), cbor_value_get_type() | |
428 | */ | |
429 | ||
430 | /** | |
431 | * Performs a basic validation of the CBOR stream pointed by \a it and returns | |
432 | * the error it found. If no error was found, it returns CborNoError and the | |
433 | * application can iterate over the items with certainty that no other errors | |
434 | * will appear during parsing. | |
435 | * | |
436 | * A basic validation checks for: | |
437 | * \list | |
438 | * \li absence of undefined additional information bytes; | |
439 | * \li well-formedness of all numbers, lengths, and simple values; | |
440 | * \li string contents match reported sizes; | |
441 | * \li arrays and maps contain the number of elements they are reported to have; | |
442 | * \endlist | |
443 | * | |
444 | * For further checks, see cbor_value_validate(). | |
445 | * | |
446 | * This function has the same timing and memory requirements as | |
447 | * cbor_value_advance(). | |
448 | * | |
449 | * \sa cbor_value_validate(), cbor_value_advance() | |
450 | */ | |
451 | CborError cbor_value_validate_basic(const CborValue *it) | |
452 | { | |
453 | CborValue value = *it; | |
454 | return cbor_value_advance(&value); | |
455 | } | |
456 | ||
457 | /** | |
458 | * Advances the CBOR value \a it by one fixed-size position. Fixed-size types | |
459 | * are: integers, tags, simple types (including boolean, null and undefined | |
460 | * values) and floating point types. | |
461 | * | |
462 | * If the type is not of fixed size, this function has undefined behavior. Code | |
463 | * must be sure that the current type is one of the fixed-size types before | |
464 | * calling this function. This function is provided because it can guarantee | |
465 | * that it runs in constant time (O(1)). | |
466 | * | |
467 | * If the caller is not able to determine whether the type is fixed or not, code | |
468 | * can use the cbor_value_advance() function instead. | |
469 | * | |
470 | * \sa cbor_value_at_end(), cbor_value_advance(), cbor_value_enter_container(), cbor_value_leave_container() | |
471 | */ | |
472 | CborError cbor_value_advance_fixed(CborValue *it) | |
473 | { | |
474 | cbor_assert(it->type != CborInvalidType); | |
475 | cbor_assert(is_fixed_type(it->type)); | |
476 | if (!it->remaining) | |
477 | return CborErrorAdvancePastEOF; | |
478 | return advance_internal(it); | |
479 | } | |
480 | ||
481 | static CborError advance_recursive(CborValue *it, int nestingLevel) | |
482 | { | |
483 | CborError err; | |
484 | CborValue recursed; | |
485 | ||
486 | if (is_fixed_type(it->type)) | |
487 | return advance_internal(it); | |
488 | ||
489 | if (!cbor_value_is_container(it)) { | |
490 | size_t len = SIZE_MAX; | |
491 | return _cbor_value_copy_string(it, NULL, &len, it); | |
492 | } | |
493 | ||
494 | /* map or array */ | |
495 | if (nestingLevel == 0) | |
496 | return CborErrorNestingTooDeep; | |
497 | ||
498 | err = cbor_value_enter_container(it, &recursed); | |
499 | if (err) | |
500 | return err; | |
501 | while (!cbor_value_at_end(&recursed)) { | |
502 | err = advance_recursive(&recursed, nestingLevel - 1); | |
503 | if (err) | |
504 | return err; | |
505 | } | |
506 | return cbor_value_leave_container(it, &recursed); | |
507 | } | |
508 | ||
509 | ||
510 | /** | |
511 | * Advances the CBOR value \a it by one element, skipping over containers. | |
512 | * Unlike cbor_value_advance_fixed(), this function can be called on a CBOR | |
513 | * value of any type. However, if the type is a container (map or array) or a | |
514 | * string with a chunked payload, this function will not run in constant time | |
515 | * and will recurse into itself (it will run on O(n) time for the number of | |
516 | * elements or chunks and will use O(n) memory for the number of nested | |
517 | * containers). | |
518 | * | |
519 | * The number of recursions can be limited at compile time to avoid stack | |
520 | * exhaustion in constrained systems. | |
521 | * | |
522 | * \sa cbor_value_at_end(), cbor_value_advance_fixed(), cbor_value_enter_container(), cbor_value_leave_container() | |
523 | */ | |
524 | CborError cbor_value_advance(CborValue *it) | |
525 | { | |
526 | cbor_assert(it->type != CborInvalidType); | |
527 | if (!it->remaining) | |
528 | return CborErrorAdvancePastEOF; | |
529 | return advance_recursive(it, CBOR_PARSER_MAX_RECURSIONS); | |
530 | } | |
531 | ||
532 | /** | |
533 | * \fn bool cbor_value_is_tag(const CborValue *value) | |
534 | * | |
535 | * Returns true if the iterator \a value is valid and points to a CBOR tag. | |
536 | * | |
537 | * \sa cbor_value_get_tag(), cbor_value_skip_tag() | |
538 | */ | |
539 | ||
540 | /** | |
541 | * \fn CborError cbor_value_get_tag(const CborValue *value, CborTag *result) | |
542 | * | |
543 | * Retrieves the CBOR tag value that \a value points to and stores it in \a | |
544 | * result. If the iterator \a value does not point to a CBOR tag value, the | |
545 | * behavior is undefined, so checking with \ref cbor_value_get_type or with | |
546 | * \ref cbor_value_is_tag is recommended. | |
547 | * | |
548 | * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_tag() | |
549 | */ | |
550 | ||
551 | /** | |
552 | * Advances the CBOR value \a it until it no longer points to a tag. If \a it is | |
553 | * already not pointing to a tag, then this function returns it unchanged. | |
554 | * | |
555 | * This function does not run in constant time: it will run on O(n) for n being | |
556 | * the number of tags. It does use constant memory (O(1) memory requirements). | |
557 | * | |
558 | * \sa cbor_value_advance_fixed(), cbor_value_advance() | |
559 | */ | |
560 | CborError cbor_value_skip_tag(CborValue *it) | |
561 | { | |
562 | while (cbor_value_is_tag(it)) { | |
563 | CborError err = cbor_value_advance_fixed(it); | |
564 | if (err) | |
565 | return err; | |
566 | } | |
567 | return CborNoError; | |
568 | } | |
569 | ||
570 | /** | |
571 | * \fn bool cbor_value_is_container(const CborValue *it) | |
572 | * | |
573 | * Returns true if the \a it value is a container and requires recursion in | |
574 | * order to decode (maps and arrays), false otherwise. | |
575 | */ | |
576 | ||
577 | /** | |
578 | * Creates a CborValue iterator pointing to the first element of the container | |
579 | * represented by \a it and saves it in \a recursed. The \a it container object | |
580 | * needs to be kept and passed again to cbor_value_leave_container() in order | |
581 | * to continue iterating past this container. | |
582 | * | |
583 | * The \a it CborValue iterator must point to a container. | |
584 | * | |
585 | * \sa cbor_value_is_container(), cbor_value_leave_container(), cbor_value_advance() | |
586 | */ | |
587 | CborError cbor_value_enter_container(const CborValue *it, CborValue *recursed) | |
588 | { | |
589 | cbor_assert(cbor_value_is_container(it)); | |
590 | *recursed = *it; | |
591 | ||
592 | if (it->flags & CborIteratorFlag_UnknownLength) { | |
593 | recursed->remaining = UINT32_MAX; | |
594 | ++recursed->ptr; | |
595 | } else { | |
596 | uint64_t len; | |
597 | CborError err = _cbor_value_extract_number(&recursed->ptr, recursed->parser->end, &len); | |
598 | cbor_assert(err == CborNoError); | |
599 | ||
600 | recursed->remaining = (uint32_t)len; | |
601 | if (recursed->remaining != len || len == UINT32_MAX) { | |
602 | /* back track the pointer to indicate where the error occurred */ | |
603 | recursed->ptr = it->ptr; | |
604 | return CborErrorDataTooLarge; | |
605 | } | |
606 | if (recursed->type == CborMapType) { | |
607 | /* maps have keys and values, so we need to multiply by 2 */ | |
608 | if (recursed->remaining > UINT32_MAX / 2) { | |
609 | /* back track the pointer to indicate where the error occurred */ | |
610 | recursed->ptr = it->ptr; | |
611 | return CborErrorDataTooLarge; | |
612 | } | |
613 | recursed->remaining *= 2; | |
614 | } | |
615 | if (len == 0) { | |
616 | /* the case of the empty container */ | |
617 | recursed->type = CborInvalidType; | |
618 | return CborNoError; | |
619 | } | |
620 | } | |
621 | return preparse_next_value_nodecrement(recursed); | |
622 | } | |
623 | ||
624 | /** | |
625 | * Updates \a it to point to the next element after the container. The \a | |
626 | * recursed object needs to point to the element obtained either by advancing | |
627 | * the last element of the container (via cbor_value_advance(), | |
628 | * cbor_value_advance_fixed(), a nested cbor_value_leave_container(), or the \c | |
629 | * next pointer from cbor_value_copy_string() or cbor_value_dup_string()). | |
630 | * | |
631 | * The \a it and \a recursed parameters must be the exact same as passed to | |
632 | * cbor_value_enter_container(). | |
633 | * | |
634 | * \sa cbor_value_enter_container(), cbor_value_at_end() | |
635 | */ | |
636 | CborError cbor_value_leave_container(CborValue *it, const CborValue *recursed) | |
637 | { | |
638 | cbor_assert(cbor_value_is_container(it)); | |
639 | cbor_assert(recursed->type == CborInvalidType); | |
640 | it->ptr = recursed->ptr; | |
641 | return preparse_next_value(it); | |
642 | } | |
643 | ||
644 | ||
645 | /** | |
646 | * \fn CborType cbor_value_get_type(const CborValue *value) | |
647 | * | |
648 | * Returns the type of the CBOR value that the iterator \a value points to. If | |
649 | * \a value does not point to a valid value, this function returns \ref | |
650 | * CborInvalidType. | |
651 | * | |
652 | * TinyCBOR also provides functions to test directly if a given CborValue object | |
653 | * is of a given type, like cbor_value_is_text_string() and cbor_value_is_null(). | |
654 | * | |
655 | * \sa cbor_value_is_valid() | |
656 | */ | |
657 | ||
658 | /** | |
659 | * \fn bool cbor_value_is_null(const CborValue *value) | |
660 | * | |
661 | * Returns true if the iterator \a value is valid and points to a CBOR null type. | |
662 | * | |
663 | * \sa cbor_value_is_valid(), cbor_value_is_undefined() | |
664 | */ | |
665 | ||
666 | /** | |
667 | * \fn bool cbor_value_is_undefined(const CborValue *value) | |
668 | * | |
669 | * Returns true if the iterator \a value is valid and points to a CBOR undefined type. | |
670 | * | |
671 | * \sa cbor_value_is_valid(), cbor_value_is_null() | |
672 | */ | |
673 | ||
674 | /** | |
675 | * \fn bool cbor_value_is_boolean(const CborValue *value) | |
676 | * | |
677 | * Returns true if the iterator \a value is valid and points to a CBOR boolean | |
678 | * type (true or false). | |
679 | * | |
680 | * \sa cbor_value_is_valid(), cbor_value_get_boolean() | |
681 | */ | |
682 | ||
683 | /** | |
684 | * \fn CborError cbor_value_get_boolean(const CborValue *value, bool *result) | |
685 | * | |
686 | * Retrieves the boolean value that \a value points to and stores it in \a | |
687 | * result. If the iterator \a value does not point to a boolean value, the | |
688 | * behavior is undefined, so checking with \ref cbor_value_get_type or with | |
689 | * \ref cbor_value_is_boolean is recommended. | |
690 | * | |
691 | * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_boolean() | |
692 | */ | |
693 | ||
694 | /** | |
695 | * \fn bool cbor_value_is_simple_type(const CborValue *value) | |
696 | * | |
697 | * Returns true if the iterator \a value is valid and points to a CBOR Simple Type | |
698 | * type (other than true, false, null and undefined). | |
699 | * | |
700 | * \sa cbor_value_is_valid(), cbor_value_get_simple_type() | |
701 | */ | |
702 | ||
703 | /** | |
704 | * \fn CborError cbor_value_get_simple_type(const CborValue *value, uint8_t *result) | |
705 | * | |
706 | * Retrieves the CBOR Simple Type value that \a value points to and stores it | |
707 | * in \a result. If the iterator \a value does not point to a simple_type | |
708 | * value, the behavior is undefined, so checking with \ref cbor_value_get_type | |
709 | * or with \ref cbor_value_is_simple_type is recommended. | |
710 | * | |
711 | * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_simple_type() | |
712 | */ | |
713 | ||
714 | /** | |
715 | * \fn bool cbor_value_is_integer(const CborValue *value) | |
716 | * | |
717 | * Returns true if the iterator \a value is valid and points to a CBOR integer | |
718 | * type. | |
719 | * | |
720 | * \sa cbor_value_is_valid(), cbor_value_get_int, cbor_value_get_int64, cbor_value_get_uint64, cbor_value_get_raw_integer | |
721 | */ | |
722 | ||
723 | /** | |
724 | * \fn bool cbor_value_is_unsigned_integer(const CborValue *value) | |
725 | * | |
726 | * Returns true if the iterator \a value is valid and points to a CBOR unsigned | |
727 | * integer type (positive values or zero). | |
728 | * | |
729 | * \sa cbor_value_is_valid(), cbor_value_get_uint64() | |
730 | */ | |
731 | ||
732 | /** | |
733 | * \fn bool cbor_value_is_negative_integer(const CborValue *value) | |
734 | * | |
735 | * Returns true if the iterator \a value is valid and points to a CBOR negative | |
736 | * integer type. | |
737 | * | |
738 | * \sa cbor_value_is_valid(), cbor_value_get_int, cbor_value_get_int64, cbor_value_get_raw_integer | |
739 | */ | |
740 | ||
741 | /** | |
742 | * \fn CborError cbor_value_get_int(const CborValue *value, int *result) | |
743 | * | |
744 | * Retrieves the CBOR integer value that \a value points to and stores it in \a | |
745 | * result. If the iterator \a value does not point to an integer value, the | |
746 | * behavior is undefined, so checking with \ref cbor_value_get_type or with | |
747 | * \ref cbor_value_is_integer is recommended. | |
748 | * | |
749 | * Note that this function does not do range-checking: integral values that do | |
750 | * not fit in a variable of type \c{int} are silently truncated to fit. Use | |
751 | * cbor_value_get_int_checked() if that is not acceptable. | |
752 | * | |
753 | * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_integer() | |
754 | */ | |
755 | ||
756 | /** | |
757 | * \fn CborError cbor_value_get_int64(const CborValue *value, int64_t *result) | |
758 | * | |
759 | * Retrieves the CBOR integer value that \a value points to and stores it in \a | |
760 | * result. If the iterator \a value does not point to an integer value, the | |
761 | * behavior is undefined, so checking with \ref cbor_value_get_type or with | |
762 | * \ref cbor_value_is_integer is recommended. | |
763 | * | |
764 | * Note that this function does not do range-checking: integral values that do | |
765 | * not fit in a variable of type \c{int64_t} are silently truncated to fit. Use | |
766 | * cbor_value_get_int64_checked() that is not acceptable. | |
767 | * | |
768 | * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_integer() | |
769 | */ | |
770 | ||
771 | /** | |
772 | * \fn CborError cbor_value_get_uint64(const CborValue *value, uint64_t *result) | |
773 | * | |
774 | * Retrieves the CBOR integer value that \a value points to and stores it in \a | |
775 | * result. If the iterator \a value does not point to an unsigned integer | |
776 | * value, the behavior is undefined, so checking with \ref cbor_value_get_type | |
777 | * or with \ref cbor_value_is_unsigned_integer is recommended. | |
778 | * | |
779 | * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_unsigned_integer() | |
780 | */ | |
781 | ||
782 | /** | |
783 | * \fn CborError cbor_value_get_raw_integer(const CborValue *value, uint64_t *result) | |
784 | * | |
785 | * Retrieves the CBOR integer value that \a value points to and stores it in \a | |
786 | * result. If the iterator \a value does not point to an integer value, the | |
787 | * behavior is undefined, so checking with \ref cbor_value_get_type or with | |
788 | * \ref cbor_value_is_integer is recommended. | |
789 | * | |
790 | * This function is provided because CBOR negative integers can assume values | |
791 | * that cannot be represented with normal 64-bit integer variables. | |
792 | * | |
793 | * If the integer is unsigned (that is, if cbor_value_is_unsigned_integer() | |
794 | * returns true), then \a result will contain the actual value. If the integer | |
795 | * is negative, then \a result will contain the absolute value of that integer, | |
796 | * minus one. That is, \c {actual = -result - 1}. On architectures using two's | |
797 | * complement for representation of negative integers, it is equivalent to say | |
798 | * that \a result will contain the bitwise negation of the actual value. | |
799 | * | |
800 | * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_integer() | |
801 | */ | |
802 | ||
803 | /** | |
804 | * Retrieves the CBOR integer value that \a value points to and stores it in \a | |
805 | * result. If the iterator \a value does not point to an integer value, the | |
806 | * behavior is undefined, so checking with \ref cbor_value_get_type or with | |
807 | * \ref cbor_value_is_integer is recommended. | |
808 | * | |
809 | * Unlike \ref cbor_value_get_int64(), this function performs a check to see if the | |
810 | * stored integer fits in \a result without data loss. If the number is outside | |
811 | * the valid range for the data type, this function returns the recoverable | |
812 | * error CborErrorDataTooLarge. In that case, use either | |
813 | * cbor_value_get_uint64() (if the number is positive) or | |
814 | * cbor_value_get_raw_integer(). | |
815 | * | |
816 | * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_integer(), cbor_value_get_int64() | |
817 | */ | |
818 | CborError cbor_value_get_int64_checked(const CborValue *value, int64_t *result) | |
819 | { | |
820 | uint64_t v; | |
821 | cbor_assert(cbor_value_is_integer(value)); | |
822 | v = _cbor_value_extract_int64_helper(value); | |
823 | ||
824 | /* Check before converting, as the standard says (C11 6.3.1.3 paragraph 3): | |
825 | * "[if] the new type is signed and the value cannot be represented in it; either the | |
826 | * result is implementation-defined or an implementation-defined signal is raised." | |
827 | * | |
828 | * The range for int64_t is -2^63 to 2^63-1 (int64_t is required to be | |
829 | * two's complement, C11 7.20.1.1 paragraph 3), which in CBOR is | |
830 | * represented the same way, differing only on the "sign bit" (the major | |
831 | * type). | |
832 | */ | |
833 | ||
834 | if (unlikely(v > (uint64_t)INT64_MAX)) | |
835 | return CborErrorDataTooLarge; | |
836 | ||
837 | *result = v; | |
838 | if (value->flags & CborIteratorFlag_NegativeInteger) | |
839 | *result = -*result - 1; | |
840 | return CborNoError; | |
841 | } | |
842 | ||
843 | /** | |
844 | * Retrieves the CBOR integer value that \a value points to and stores it in \a | |
845 | * result. If the iterator \a value does not point to an integer value, the | |
846 | * behavior is undefined, so checking with \ref cbor_value_get_type or with | |
847 | * \ref cbor_value_is_integer is recommended. | |
848 | * | |
849 | * Unlike \ref cbor_value_get_int(), this function performs a check to see if the | |
850 | * stored integer fits in \a result without data loss. If the number is outside | |
851 | * the valid range for the data type, this function returns the recoverable | |
852 | * error CborErrorDataTooLarge. In that case, use one of the other integer | |
853 | * functions to obtain the value. | |
854 | * | |
855 | * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_integer(), cbor_value_get_int64(), | |
856 | * cbor_value_get_uint64(), cbor_value_get_int64_checked(), cbor_value_get_raw_integer() | |
857 | */ | |
858 | CborError cbor_value_get_int_checked(const CborValue *value, int *result) | |
859 | { | |
860 | uint64_t v; | |
861 | cbor_assert(cbor_value_is_integer(value)); | |
862 | v = _cbor_value_extract_int64_helper(value); | |
863 | ||
864 | /* Check before converting, as the standard says (C11 6.3.1.3 paragraph 3): | |
865 | * "[if] the new type is signed and the value cannot be represented in it; either the | |
866 | * result is implementation-defined or an implementation-defined signal is raised." | |
867 | * | |
868 | * But we can convert from signed to unsigned without fault (paragraph 2). | |
869 | * | |
870 | * The range for int is implementation-defined and int is not guaranteed to use | |
871 | * two's complement representation (although int32_t is). | |
872 | */ | |
873 | ||
874 | if (value->flags & CborIteratorFlag_NegativeInteger) { | |
875 | if (unlikely(v > (unsigned) -(INT_MIN + 1))) | |
876 | return CborErrorDataTooLarge; | |
877 | ||
878 | *result = (int)v; | |
879 | *result = -*result - 1; | |
880 | } else { | |
881 | if (unlikely(v > (uint64_t)INT_MAX)) | |
882 | return CborErrorDataTooLarge; | |
883 | ||
884 | *result = (int)v; | |
885 | } | |
886 | return CborNoError; | |
887 | ||
888 | } | |
889 | ||
890 | /** | |
891 | * \fn bool cbor_value_is_length_known(const CborValue *value) | |
892 | * | |
893 | * Returns true if the length of this type is known without calculation. That | |
894 | * is, if the length of this CBOR string, map or array is encoded in the data | |
895 | * stream, this function returns true. If the length is not encoded, it returns | |
896 | * false. | |
897 | * | |
898 | * If the length is known, code can call cbor_value_get_string_length(), | |
899 | * cbor_value_get_array_length() or cbor_value_get_map_length() to obtain the | |
900 | * length. If the length is not known but is necessary, code can use the | |
901 | * cbor_value_calculate_string_length() function (no equivalent function is | |
902 | * provided for maps and arrays). | |
903 | */ | |
904 | ||
905 | /** | |
906 | * \fn bool cbor_value_is_text_string(const CborValue *value) | |
907 | * | |
908 | * Returns true if the iterator \a value is valid and points to a CBOR text | |
909 | * string. CBOR text strings are UTF-8 encoded and usually contain | |
910 | * human-readable text. | |
911 | * | |
912 | * \sa cbor_value_is_valid(), cbor_value_get_string_length(), cbor_value_calculate_string_length(), | |
913 | * cbor_value_copy_text_string(), cbor_value_dup_text_string() | |
914 | */ | |
915 | ||
916 | /** | |
917 | * \fn bool cbor_value_is_byte_string(const CborValue *value) | |
918 | * | |
919 | * Returns true if the iterator \a value is valid and points to a CBOR text | |
920 | * string. CBOR byte strings are binary data with no specified encoding or | |
921 | * format. | |
922 | * | |
923 | * \sa cbor_value_is_valid(), cbor_value_get_string_length(), cbor_value_calculate_string_length(), | |
924 | * cbor_value_copy_byte_string(), cbor_value_dup_byte_string() | |
925 | */ | |
926 | ||
927 | /** | |
928 | * \fn CborError cbor_value_get_string_length(const CborValue *value, size_t *length) | |
929 | * | |
930 | * Extracts the length of the byte or text string that \a value points to and | |
931 | * stores it in \a result. If the iterator \a value does not point to a text | |
932 | * string or a byte string, the behaviour is undefined, so checking with \ref | |
933 | * cbor_value_get_type, with \ref cbor_value_is_text_string or \ref | |
934 | * cbor_value_is_byte_string is recommended. | |
935 | * | |
936 | * If the length of this string is not encoded in the CBOR data stream, this | |
937 | * function will return the recoverable error CborErrorUnknownLength. You may | |
938 | * also check whether that is the case by using cbor_value_is_length_known(). | |
939 | * | |
940 | * If the length of the string is required but the length was not encoded, use | |
941 | * cbor_value_calculate_string_length(), but note that that function does not | |
942 | * run in constant time. | |
943 | * | |
944 | * \note On 32-bit platforms, this function will return error condition of \ref | |
945 | * CborErrorDataTooLarge if the stream indicates a length that is too big to | |
946 | * fit in 32-bit. | |
947 | * | |
948 | * \sa cbor_value_is_valid(), cbor_value_is_length_known(), cbor_value_calculate_string_length() | |
949 | */ | |
950 | ||
951 | /** | |
952 | * Calculates the length of the byte or text string that \a value points to and | |
953 | * stores it in \a len. If the iterator \a value does not point to a text | |
954 | * string or a byte string, the behaviour is undefined, so checking with \ref | |
955 | * cbor_value_get_type, with \ref cbor_value_is_text_string or \ref | |
956 | * cbor_value_is_byte_string is recommended. | |
957 | * | |
958 | * This function is different from cbor_value_get_string_length() in that it | |
959 | * calculates the length even for strings sent in chunks. For that reason, this | |
960 | * function may not run in constant time (it will run in O(n) time on the | |
961 | * number of chunks). It does use constant memory (O(1)). | |
962 | * | |
963 | * \note On 32-bit platforms, this function will return error condition of \ref | |
964 | * CborErrorDataTooLarge if the stream indicates a length that is too big to | |
965 | * fit in 32-bit. | |
966 | * | |
967 | * \sa cbor_value_get_string_length(), cbor_value_copy_text_string(), cbor_value_copy_byte_string(), cbor_value_is_length_known() | |
968 | */ | |
969 | CborError cbor_value_calculate_string_length(const CborValue *value, size_t *len) | |
970 | { | |
971 | *len = SIZE_MAX; | |
972 | return _cbor_value_copy_string(value, NULL, len, NULL); | |
973 | } | |
974 | ||
975 | static inline void prepare_string_iteration(CborValue *it) | |
976 | { | |
977 | if (!cbor_value_is_length_known(it)) { | |
978 | /* chunked string: we're before the first chunk; | |
979 | * advance to the first chunk */ | |
980 | ++it->ptr; | |
981 | it->flags |= CborIteratorFlag_IteratingStringChunks; | |
982 | } | |
983 | } | |
984 | ||
985 | CborError CBOR_INTERNAL_API_CC _cbor_value_prepare_string_iteration(CborValue *it) | |
986 | { | |
987 | cbor_assert((it->flags & CborIteratorFlag_IteratingStringChunks) == 0); | |
988 | prepare_string_iteration(it); | |
989 | ||
990 | /* are we at the end? */ | |
991 | if (it->ptr == it->parser->end) | |
992 | return CborErrorUnexpectedEOF; | |
993 | return CborNoError; | |
994 | } | |
995 | ||
996 | static CborError get_string_chunk(CborValue *it, const void **bufferptr, size_t *len) | |
997 | { | |
998 | CborError err; | |
999 | ||
1000 | /* Possible states: | |
1001 | * length known | iterating | meaning | |
1002 | * no | no | before the first chunk of a chunked string | |
1003 | * yes | no | at a non-chunked string | |
1004 | * no | yes | second or later chunk | |
1005 | * yes | yes | after a non-chunked string | |
1006 | */ | |
1007 | if (it->flags & CborIteratorFlag_IteratingStringChunks) { | |
1008 | /* already iterating */ | |
1009 | if (cbor_value_is_length_known(it)) { | |
1010 | /* if the length was known, it wasn't chunked, so finish iteration */ | |
1011 | goto last_chunk; | |
1012 | } | |
1013 | } else { | |
1014 | prepare_string_iteration(it); | |
1015 | } | |
1016 | ||
1017 | /* are we at the end? */ | |
1018 | if (it->ptr == it->parser->end) | |
1019 | return CborErrorUnexpectedEOF; | |
1020 | ||
1021 | if (*it->ptr == BreakByte) { | |
1022 | /* last chunk */ | |
1023 | ++it->ptr; | |
1024 | last_chunk: | |
1025 | *bufferptr = NULL; | |
1026 | *len = 0; | |
1027 | return preparse_next_value(it); | |
1028 | } else if ((uint8_t)(*it->ptr & MajorTypeMask) == it->type) { | |
1029 | err = extract_length(it->parser, &it->ptr, len); | |
1030 | if (err) | |
1031 | return err; | |
1032 | if (*len > (size_t)(it->parser->end - it->ptr)) | |
1033 | return CborErrorUnexpectedEOF; | |
1034 | ||
1035 | *bufferptr = it->ptr; | |
1036 | it->ptr += *len; | |
1037 | } else { | |
1038 | return CborErrorIllegalType; | |
1039 | } | |
1040 | ||
1041 | it->flags |= CborIteratorFlag_IteratingStringChunks; | |
1042 | return CborNoError; | |
1043 | } | |
1044 | ||
1045 | CborError CBOR_INTERNAL_API_CC | |
1046 | _cbor_value_get_string_chunk(const CborValue *value, const void **bufferptr, | |
1047 | size_t *len, CborValue *next) | |
1048 | { | |
1049 | CborValue tmp; | |
1050 | if (!next) | |
1051 | next = &tmp; | |
1052 | *next = *value; | |
1053 | return get_string_chunk(next, bufferptr, len); | |
1054 | } | |
1055 | ||
1056 | /* We return uintptr_t so that we can pass memcpy directly as the iteration | |
1057 | * function. The choice is to optimize for memcpy, which is used in the base | |
1058 | * parser API (cbor_value_copy_string), while memcmp is used in convenience API | |
1059 | * only. */ | |
1060 | typedef uintptr_t (*IterateFunction)(char *, const uint8_t *, size_t); | |
1061 | ||
1062 | static uintptr_t iterate_noop(char *dest, const uint8_t *src, size_t len) | |
1063 | { | |
1064 | (void)dest; | |
1065 | (void)src; | |
1066 | (void)len; | |
1067 | return true; | |
1068 | } | |
1069 | ||
1070 | static uintptr_t iterate_memcmp(char *s1, const uint8_t *s2, size_t len) | |
1071 | { | |
1072 | return memcmp(s1, (const char *)s2, len) == 0; | |
1073 | } | |
1074 | ||
1075 | static uintptr_t iterate_memcpy(char *dest, const uint8_t *src, size_t len) | |
1076 | { | |
1077 | return (uintptr_t)memcpy(dest, src, len); | |
1078 | } | |
1079 | ||
1080 | static CborError iterate_string_chunks(const CborValue *value, char *buffer, size_t *buflen, | |
1081 | bool *result, CborValue *next, IterateFunction func) | |
1082 | { | |
1083 | CborError err; | |
1084 | CborValue tmp; | |
1085 | size_t total = 0; | |
1086 | const void *ptr; | |
1087 | ||
1088 | cbor_assert(cbor_value_is_byte_string(value) || cbor_value_is_text_string(value)); | |
1089 | if (!next) | |
1090 | next = &tmp; | |
1091 | *next = *value; | |
1092 | *result = true; | |
1093 | ||
1094 | while (1) { | |
1095 | size_t newTotal; | |
1096 | size_t chunkLen; | |
1097 | err = get_string_chunk(next, &ptr, &chunkLen); | |
1098 | if (err) | |
1099 | return err; | |
1100 | if (!ptr) | |
1101 | break; | |
1102 | ||
1103 | if (unlikely(add_check_overflow(total, chunkLen, &newTotal))) | |
1104 | return CborErrorDataTooLarge; | |
1105 | ||
1106 | if (*result && *buflen >= newTotal) | |
1107 | *result = !!func(buffer + total, (const uint8_t *)ptr, chunkLen); | |
1108 | else | |
1109 | *result = false; | |
1110 | ||
1111 | total = newTotal; | |
1112 | } | |
1113 | ||
1114 | /* is there enough room for the ending NUL byte? */ | |
1115 | if (*result && *buflen > total) { | |
1116 | uint8_t nul[] = { 0 }; | |
1117 | *result = !!func(buffer + total, nul, 1); | |
1118 | } | |
1119 | *buflen = total; | |
1120 | return CborNoError; | |
1121 | } | |
1122 | ||
1123 | /** | |
1124 | * \fn CborError cbor_value_copy_text_string(const CborValue *value, char *buffer, size_t *buflen, CborValue *next) | |
1125 | * | |
1126 | * Copies the string pointed to by \a value into the buffer provided at \a buffer | |
1127 | * of \a buflen bytes. If \a buffer is a NULL pointer, this function will not | |
1128 | * copy anything and will only update the \a next value. | |
1129 | * | |
1130 | * If the iterator \a value does not point to a text string, the behaviour is | |
1131 | * undefined, so checking with \ref cbor_value_get_type or \ref | |
1132 | * cbor_value_is_text_string is recommended. | |
1133 | * | |
1134 | * If the provided buffer length was too small, this function returns an error | |
1135 | * condition of \ref CborErrorOutOfMemory. If you need to calculate the length | |
1136 | * of the string in order to preallocate a buffer, use | |
1137 | * cbor_value_calculate_string_length(). | |
1138 | * | |
1139 | * On success, this function sets the number of bytes copied to \c{*buflen}. If | |
1140 | * the buffer is large enough, this function will insert a null byte after the | |
1141 | * last copied byte, to facilitate manipulation of text strings. That byte is | |
1142 | * not included in the returned value of \c{*buflen}. If there was no space for | |
1143 | * the terminating null, no error is returned, so callers must check the value | |
1144 | * of *buflen after the call, before relying on the '\0'; if it has not been | |
1145 | * changed by the call, there is no '\0'-termination on the buffer's contents. | |
1146 | * | |
1147 | * The \a next pointer, if not null, will be updated to point to the next item | |
1148 | * after this string. If \a value points to the last item, then \a next will be | |
1149 | * invalid. | |
1150 | * | |
1151 | * This function may not run in constant time (it will run in O(n) time on the | |
1152 | * number of chunks). It requires constant memory (O(1)). | |
1153 | * | |
1154 | * \note This function does not perform UTF-8 validation on the incoming text | |
1155 | * string. | |
1156 | * | |
1157 | * \sa cbor_value_get_text_string_chunk() cbor_value_dup_text_string(), cbor_value_copy_byte_string(), cbor_value_get_string_length(), cbor_value_calculate_string_length() | |
1158 | */ | |
1159 | ||
1160 | /** | |
1161 | * \fn CborError cbor_value_copy_byte_string(const CborValue *value, uint8_t *buffer, size_t *buflen, CborValue *next) | |
1162 | * | |
1163 | * Copies the string pointed by \a value into the buffer provided at \a buffer | |
1164 | * of \a buflen bytes. If \a buffer is a NULL pointer, this function will not | |
1165 | * copy anything and will only update the \a next value. | |
1166 | * | |
1167 | * If the iterator \a value does not point to a byte string, the behaviour is | |
1168 | * undefined, so checking with \ref cbor_value_get_type or \ref | |
1169 | * cbor_value_is_byte_string is recommended. | |
1170 | * | |
1171 | * If the provided buffer length was too small, this function returns an error | |
1172 | * condition of \ref CborErrorOutOfMemory. If you need to calculate the length | |
1173 | * of the string in order to preallocate a buffer, use | |
1174 | * cbor_value_calculate_string_length(). | |
1175 | * | |
1176 | * On success, this function sets the number of bytes copied to \c{*buflen}. If | |
1177 | * the buffer is large enough, this function will insert a null byte after the | |
1178 | * last copied byte, to facilitate manipulation of null-terminated strings. | |
1179 | * That byte is not included in the returned value of \c{*buflen}. | |
1180 | * | |
1181 | * The \a next pointer, if not null, will be updated to point to the next item | |
1182 | * after this string. If \a value points to the last item, then \a next will be | |
1183 | * invalid. | |
1184 | * | |
1185 | * This function may not run in constant time (it will run in O(n) time on the | |
1186 | * number of chunks). It requires constant memory (O(1)). | |
1187 | * | |
1188 | * \sa cbor_value_get_byte_string_chunk(), cbor_value_dup_text_string(), cbor_value_copy_text_string(), cbor_value_get_string_length(), cbor_value_calculate_string_length() | |
1189 | */ | |
1190 | ||
1191 | CborError _cbor_value_copy_string(const CborValue *value, void *buffer, | |
1192 | size_t *buflen, CborValue *next) | |
1193 | { | |
1194 | bool copied_all; | |
1195 | CborError err = iterate_string_chunks(value, (char*)buffer, buflen, &copied_all, next, | |
1196 | buffer ? iterate_memcpy : iterate_noop); | |
1197 | return err ? err : | |
1198 | copied_all ? CborNoError : CborErrorOutOfMemory; | |
1199 | } | |
1200 | ||
1201 | /** | |
1202 | * Compares the entry \a value with the string \a string and stores the result | |
1203 | * in \a result. If the value is different from \a string \a result will | |
1204 | * contain \c false. | |
1205 | * | |
1206 | * The entry at \a value may be a tagged string. If \a value is not a string or | |
1207 | * a tagged string, the comparison result will be false. | |
1208 | * | |
1209 | * CBOR requires text strings to be encoded in UTF-8, but this function does | |
1210 | * not validate either the strings in the stream or the string \a string to be | |
1211 | * matched. Moreover, comparison is done on strict codepoint comparison, | |
1212 | * without any Unicode normalization. | |
1213 | * | |
1214 | * This function may not run in constant time (it will run in O(n) time on the | |
1215 | * number of chunks). It requires constant memory (O(1)). | |
1216 | * | |
1217 | * \sa cbor_value_skip_tag(), cbor_value_copy_text_string() | |
1218 | */ | |
1219 | CborError cbor_value_text_string_equals(const CborValue *value, const char *string, bool *result) | |
1220 | { | |
1221 | size_t len; | |
1222 | CborValue copy = *value; | |
1223 | CborError err = cbor_value_skip_tag(©); | |
1224 | if (err) | |
1225 | return err; | |
1226 | if (!cbor_value_is_text_string(©)) { | |
1227 | *result = false; | |
1228 | return CborNoError; | |
1229 | } | |
1230 | ||
1231 | len = strlen(string); | |
1232 | return iterate_string_chunks(©, CONST_CAST(char *, string), &len, result, NULL, iterate_memcmp); | |
1233 | } | |
1234 | ||
1235 | /** | |
1236 | * \fn bool cbor_value_is_array(const CborValue *value) | |
1237 | * | |
1238 | * Returns true if the iterator \a value is valid and points to a CBOR array. | |
1239 | * | |
1240 | * \sa cbor_value_is_valid(), cbor_value_is_map() | |
1241 | */ | |
1242 | ||
1243 | /** | |
1244 | * \fn CborError cbor_value_get_array_length(const CborValue *value, size_t *length) | |
1245 | * | |
1246 | * Extracts the length of the CBOR array that \a value points to and stores it | |
1247 | * in \a result. If the iterator \a value does not point to a CBOR array, the | |
1248 | * behaviour is undefined, so checking with \ref cbor_value_get_type or \ref | |
1249 | * cbor_value_is_array is recommended. | |
1250 | * | |
1251 | * If the length of this array is not encoded in the CBOR data stream, this | |
1252 | * function will return the recoverable error CborErrorUnknownLength. You may | |
1253 | * also check whether that is the case by using cbor_value_is_length_known(). | |
1254 | * | |
1255 | * \note On 32-bit platforms, this function will return error condition of \ref | |
1256 | * CborErrorDataTooLarge if the stream indicates a length that is too big to | |
1257 | * fit in 32-bit. | |
1258 | * | |
1259 | * \sa cbor_value_is_valid(), cbor_value_is_length_known() | |
1260 | */ | |
1261 | ||
1262 | /** | |
1263 | * \fn bool cbor_value_is_map(const CborValue *value) | |
1264 | * | |
1265 | * Returns true if the iterator \a value is valid and points to a CBOR map. | |
1266 | * | |
1267 | * \sa cbor_value_is_valid(), cbor_value_is_array() | |
1268 | */ | |
1269 | ||
1270 | /** | |
1271 | * \fn CborError cbor_value_get_map_length(const CborValue *value, size_t *length) | |
1272 | * | |
1273 | * Extracts the length of the CBOR map that \a value points to and stores it in | |
1274 | * \a result. If the iterator \a value does not point to a CBOR map, the | |
1275 | * behaviour is undefined, so checking with \ref cbor_value_get_type or \ref | |
1276 | * cbor_value_is_map is recommended. | |
1277 | * | |
1278 | * If the length of this map is not encoded in the CBOR data stream, this | |
1279 | * function will return the recoverable error CborErrorUnknownLength. You may | |
1280 | * also check whether that is the case by using cbor_value_is_length_known(). | |
1281 | * | |
1282 | * \note On 32-bit platforms, this function will return error condition of \ref | |
1283 | * CborErrorDataTooLarge if the stream indicates a length that is too big to | |
1284 | * fit in 32-bit. | |
1285 | * | |
1286 | * \sa cbor_value_is_valid(), cbor_value_is_length_known() | |
1287 | */ | |
1288 | ||
1289 | /** | |
1290 | * Attempts to find the value in map \a map that corresponds to the text string | |
1291 | * entry \a string. If the iterator \a value does not point to a CBOR map, the | |
1292 | * behaviour is undefined, so checking with \ref cbor_value_get_type or \ref | |
1293 | * cbor_value_is_map is recommended. | |
1294 | * | |
1295 | * If the item is found, it is stored in \a result. If no item is found | |
1296 | * matching the key, then \a result will contain an element of type \ref | |
1297 | * CborInvalidType. Matching is performed using | |
1298 | * cbor_value_text_string_equals(), so tagged strings will also match. | |
1299 | * | |
1300 | * This function has a time complexity of O(n) where n is the number of | |
1301 | * elements in the map to be searched. In addition, this function is has O(n) | |
1302 | * memory requirement based on the number of nested containers (maps or arrays) | |
1303 | * found as elements of this map. | |
1304 | * | |
1305 | * \sa cbor_value_is_valid(), cbor_value_text_string_equals(), cbor_value_advance() | |
1306 | */ | |
1307 | CborError cbor_value_map_find_value(const CborValue *map, const char *string, CborValue *element) | |
1308 | { | |
1309 | CborError err; | |
1310 | size_t len = strlen(string); | |
1311 | cbor_assert(cbor_value_is_map(map)); | |
1312 | err = cbor_value_enter_container(map, element); | |
1313 | if (err) | |
1314 | goto error; | |
1315 | ||
1316 | while (!cbor_value_at_end(element)) { | |
1317 | /* find the non-tag so we can compare */ | |
1318 | err = cbor_value_skip_tag(element); | |
1319 | if (err) | |
1320 | goto error; | |
1321 | if (cbor_value_is_text_string(element)) { | |
1322 | bool equals; | |
1323 | size_t dummyLen = len; | |
1324 | err = iterate_string_chunks(element, CONST_CAST(char *, string), &dummyLen, | |
1325 | &equals, element, iterate_memcmp); | |
1326 | if (err) | |
1327 | goto error; | |
1328 | if (equals) | |
1329 | return preparse_value(element); | |
1330 | } else { | |
1331 | /* skip this key */ | |
1332 | err = cbor_value_advance(element); | |
1333 | if (err) | |
1334 | goto error; | |
1335 | } | |
1336 | ||
1337 | /* skip this value */ | |
1338 | err = cbor_value_skip_tag(element); | |
1339 | if (err) | |
1340 | goto error; | |
1341 | err = cbor_value_advance(element); | |
1342 | if (err) | |
1343 | goto error; | |
1344 | } | |
1345 | ||
1346 | /* not found */ | |
1347 | element->type = CborInvalidType; | |
1348 | return CborNoError; | |
1349 | ||
1350 | error: | |
1351 | element->type = CborInvalidType; | |
1352 | return err; | |
1353 | } | |
1354 | ||
1355 | /** | |
1356 | * \fn bool cbor_value_is_float(const CborValue *value) | |
1357 | * | |
1358 | * Returns true if the iterator \a value is valid and points to a CBOR | |
1359 | * single-precision floating point (32-bit). | |
1360 | * | |
1361 | * \sa cbor_value_is_valid(), cbor_value_is_double(), cbor_value_is_half_float() | |
1362 | */ | |
1363 | ||
1364 | /** | |
1365 | * \fn CborError cbor_value_get_float(const CborValue *value, float *result) | |
1366 | * | |
1367 | * Retrieves the CBOR single-precision floating point (32-bit) value that \a | |
1368 | * value points to and stores it in \a result. If the iterator \a value does | |
1369 | * not point to a single-precision floating point value, the behavior is | |
1370 | * undefined, so checking with \ref cbor_value_get_type or with \ref | |
1371 | * cbor_value_is_float is recommended. | |
1372 | * | |
1373 | * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_float(), cbor_value_get_double() | |
1374 | */ | |
1375 | ||
1376 | /** | |
1377 | * \fn bool cbor_value_is_double(const CborValue *value) | |
1378 | * | |
1379 | * Returns true if the iterator \a value is valid and points to a CBOR | |
1380 | * double-precision floating point (64-bit). | |
1381 | * | |
1382 | * \sa cbor_value_is_valid(), cbor_value_is_float(), cbor_value_is_half_float() | |
1383 | */ | |
1384 | ||
1385 | /** | |
1386 | * \fn CborError cbor_value_get_double(const CborValue *value, float *result) | |
1387 | * | |
1388 | * Retrieves the CBOR double-precision floating point (64-bit) value that \a | |
1389 | * value points to and stores it in \a result. If the iterator \a value does | |
1390 | * not point to a double-precision floating point value, the behavior is | |
1391 | * undefined, so checking with \ref cbor_value_get_type or with \ref | |
1392 | * cbor_value_is_double is recommended. | |
1393 | * | |
1394 | * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_double(), cbor_value_get_float() | |
1395 | */ | |
1396 | ||
1397 | /** | |
1398 | * \fn bool cbor_value_is_half_float(const CborValue *value) | |
1399 | * | |
1400 | * Returns true if the iterator \a value is valid and points to a CBOR | |
1401 | * single-precision floating point (16-bit). | |
1402 | * | |
1403 | * \sa cbor_value_is_valid(), cbor_value_is_double(), cbor_value_is_float() | |
1404 | */ | |
1405 | ||
1406 | /** | |
1407 | * Retrieves the CBOR half-precision floating point (16-bit) value that \a | |
1408 | * value points to and stores it in \a result. If the iterator \a value does | |
1409 | * not point to a half-precision floating point value, the behavior is | |
1410 | * undefined, so checking with \ref cbor_value_get_type or with \ref | |
1411 | * cbor_value_is_half_float is recommended. | |
1412 | * | |
1413 | * Note: since the C language does not have a standard type for half-precision | |
1414 | * floating point, this function takes a \c{void *} as a parameter for the | |
1415 | * storage area, which must be at least 16 bits wide. | |
1416 | * | |
1417 | * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_half_float(), cbor_value_get_float() | |
1418 | */ | |
1419 | CborError cbor_value_get_half_float(const CborValue *value, void *result) | |
1420 | { | |
1421 | uint16_t v; | |
1422 | cbor_assert(cbor_value_is_half_float(value)); | |
1423 | ||
1424 | /* size has been computed already */ | |
1425 | v = get16(value->ptr + 1); | |
1426 | memcpy(result, &v, sizeof(v)); | |
1427 | return CborNoError; | |
1428 | } | |
1429 | ||
1430 | /** @} */ |