1 /*
2  * This file has been copied from the zcbor library.
3  * Commit zcbor 0.8.1
4  */
5 
6 /*
7  * Copyright (c) 2020 Nordic Semiconductor ASA
8  *
9  * SPDX-License-Identifier: Apache-2.0
10  */
11 
12 #include <stddef.h>
13 #include <stdbool.h>
14 #include <stdint.h>
15 #include <string.h>
16 #include "zcbor_common.h"
17 #include "zcbor_print.h"
18 
19 _Static_assert((sizeof(size_t) == sizeof(void *)),
20 	"This code needs size_t to be the same length as pointers.");
21 
22 _Static_assert((sizeof(zcbor_state_t) >= sizeof(struct zcbor_state_constant)),
23 	"This code needs zcbor_state_t to be at least as large as zcbor_backups_t.");
24 
zcbor_new_backup(zcbor_state_t * state,size_t new_elem_count)25 bool zcbor_new_backup(zcbor_state_t *state, size_t new_elem_count)
26 {
27 	ZCBOR_CHECK_ERROR();
28 
29 	if ((state->constant_state->current_backup)
30 		>= state->constant_state->num_backups) {
31 		ZCBOR_ERR(ZCBOR_ERR_NO_BACKUP_MEM);
32 	}
33 
34 	state->payload_moved = false;
35 
36 	(state->constant_state->current_backup)++;
37 
38 	/* use the backup at current_backup - 1, since otherwise, the 0th
39 	 * backup would be unused. */
40 	size_t i = (state->constant_state->current_backup) - 1;
41 
42 	memcpy(&state->constant_state->backup_list[i], state,
43 		sizeof(zcbor_state_t));
44 
45 	state->elem_count = new_elem_count;
46 
47 	zcbor_log("New backup (level %zu)\n", i);
48 
49 	return true;
50 }
51 
52 
zcbor_process_backup(zcbor_state_t * state,uint32_t flags,size_t max_elem_count)53 bool zcbor_process_backup(zcbor_state_t *state, uint32_t flags,
54 		size_t max_elem_count)
55 {
56 	ZCBOR_CHECK_ERROR();
57 	zcbor_state_t local_copy = *state;
58 
59 	if (state->constant_state->current_backup == 0) {
60 		zcbor_log("No backups available.\r\n");
61 		ZCBOR_ERR(ZCBOR_ERR_NO_BACKUP_ACTIVE);
62 	}
63 
64 	/* use the backup at current_backup - 1, since otherwise, the
65 		* 0th backup would be unused. */
66 	size_t i = state->constant_state->current_backup - 1;
67 
68 	zcbor_log("Process backup (level %zu, flags 0x%x)\n", i, flags);
69 
70 	if (flags & ZCBOR_FLAG_RESTORE) {
71 		if (!(flags & ZCBOR_FLAG_KEEP_PAYLOAD)) {
72 			if (state->constant_state->backup_list[i].payload_moved) {
73 				zcbor_log("Payload pointer out of date.\r\n");
74 				ZCBOR_ERR(ZCBOR_ERR_PAYLOAD_OUTDATED);
75 			}
76 		}
77 		memcpy(state, &state->constant_state->backup_list[i],
78 			sizeof(zcbor_state_t));
79 	}
80 
81 	if (flags & ZCBOR_FLAG_CONSUME) {
82 		state->constant_state->current_backup--;
83 	}
84 
85 	if (local_copy.elem_count > max_elem_count) {
86 		zcbor_log("elem_count: %zu (expected max %zu)\r\n",
87 			local_copy.elem_count, max_elem_count);
88 		ZCBOR_ERR(ZCBOR_ERR_HIGH_ELEM_COUNT);
89 	}
90 
91 	if (flags & ZCBOR_FLAG_KEEP_PAYLOAD) {
92 		state->payload = local_copy.payload;
93 	}
94 
95 	if (flags & ZCBOR_FLAG_KEEP_DECODE_STATE) {
96 		/* Copy decode state */
97 		state->decode_state = local_copy.decode_state;
98 	}
99 
100 	return true;
101 }
102 
update_backups(zcbor_state_t * state,uint8_t const * new_payload_end)103 static void update_backups(zcbor_state_t *state, uint8_t const *new_payload_end)
104 {
105 	if (state->constant_state) {
106 		for (unsigned int i = 0; i < state->constant_state->current_backup; i++) {
107 			state->constant_state->backup_list[i].payload_end = new_payload_end;
108 			state->constant_state->backup_list[i].payload_moved = true;
109 		}
110 	}
111 }
112 
113 
zcbor_union_start_code(zcbor_state_t * state)114 bool zcbor_union_start_code(zcbor_state_t *state)
115 {
116 	if (!zcbor_new_backup(state, state->elem_count)) {
117 		ZCBOR_FAIL();
118 	}
119 	return true;
120 }
121 
122 
zcbor_union_elem_code(zcbor_state_t * state)123 bool zcbor_union_elem_code(zcbor_state_t *state)
124 {
125 	if (!zcbor_process_backup(state, ZCBOR_FLAG_RESTORE, state->elem_count)) {
126 		ZCBOR_FAIL();
127 	}
128 	return true;
129 }
130 
zcbor_union_end_code(zcbor_state_t * state)131 bool zcbor_union_end_code(zcbor_state_t *state)
132 {
133 	if (!zcbor_process_backup(state, ZCBOR_FLAG_CONSUME, state->elem_count)) {
134 		ZCBOR_FAIL();
135 	}
136 	return true;
137 }
138 
zcbor_new_state(zcbor_state_t * state_array,size_t n_states,const uint8_t * payload,size_t payload_len,size_t elem_count,uint8_t * flags,size_t flags_bytes)139 void zcbor_new_state(zcbor_state_t *state_array, size_t n_states,
140 		const uint8_t *payload, size_t payload_len, size_t elem_count,
141 		uint8_t *flags, size_t flags_bytes)
142 {
143 	state_array[0].payload = payload;
144 	state_array[0].payload_end = payload + payload_len;
145 	state_array[0].elem_count = elem_count;
146 	state_array[0].payload_moved = false;
147 	state_array[0].decode_state.indefinite_length_array = false;
148 #ifdef ZCBOR_MAP_SMART_SEARCH
149 	state_array[0].decode_state.map_search_elem_state = flags;
150 	state_array[0].decode_state.map_elem_count = 0;
151 #else
152 	state_array[0].decode_state.map_elems_processed = 0;
153 	(void)flags;
154 	(void)flags_bytes;
155 #endif
156 	state_array[0].constant_state = NULL;
157 
158 	if (n_states < 2) {
159 		return;
160 	}
161 
162 	/* Use the last state as a struct zcbor_state_constant object. */
163 	state_array[0].constant_state = (struct zcbor_state_constant *)&state_array[n_states - 1];
164 	state_array[0].constant_state->backup_list = NULL;
165 	state_array[0].constant_state->num_backups = n_states - 2;
166 	state_array[0].constant_state->current_backup = 0;
167 	state_array[0].constant_state->error = ZCBOR_SUCCESS;
168 #ifdef ZCBOR_STOP_ON_ERROR
169 	state_array[0].constant_state->stop_on_error = false;
170 #endif
171 	state_array[0].constant_state->manually_process_elem = false;
172 #ifdef ZCBOR_MAP_SMART_SEARCH
173 	state_array[0].constant_state->map_search_elem_state_end = flags + flags_bytes;
174 #endif
175 	if (n_states > 2) {
176 		state_array[0].constant_state->backup_list = &state_array[1];
177 	}
178 }
179 
zcbor_update_state(zcbor_state_t * state,const uint8_t * payload,size_t payload_len)180 void zcbor_update_state(zcbor_state_t *state,
181 		const uint8_t *payload, size_t payload_len)
182 {
183 	state->payload = payload;
184 	state->payload_end = payload + payload_len;
185 
186 	update_backups(state, state->payload_end);
187 }
188 
189 
zcbor_validate_string_fragments(struct zcbor_string_fragment * fragments,size_t num_fragments)190 bool zcbor_validate_string_fragments(struct zcbor_string_fragment *fragments,
191 		size_t num_fragments)
192 {
193 	size_t total_len = 0;
194 
195 	if (fragments == NULL) {
196 		return false;
197 	}
198 
199 	for (size_t i = 0; i < num_fragments; i++) {
200 		if (fragments[i].offset != total_len) {
201 			return false;
202 		}
203 		if (fragments[i].fragment.value == NULL) {
204 			return false;
205 		}
206 		if (fragments[i].total_len != fragments[0].total_len) {
207 			return false;
208 		}
209 		total_len += fragments[i].fragment.len;
210 		if (total_len > fragments[0].total_len) {
211 			return false;
212 		}
213 	}
214 
215 	if (num_fragments && total_len != fragments[0].total_len) {
216 		return false;
217 	}
218 
219 	if (num_fragments && (fragments[0].total_len == ZCBOR_STRING_FRAGMENT_UNKNOWN_LENGTH)) {
220 		for (size_t i = 0; i < num_fragments; i++) {
221 			fragments[i].total_len = total_len;
222 		}
223 	}
224 
225 	return true;
226 }
227 
zcbor_splice_string_fragments(struct zcbor_string_fragment * fragments,size_t num_fragments,uint8_t * result,size_t * result_len)228 bool zcbor_splice_string_fragments(struct zcbor_string_fragment *fragments,
229 		size_t num_fragments, uint8_t *result, size_t *result_len)
230 {
231 	size_t total_len = 0;
232 
233 	if (!fragments) {
234 		return false;
235 	}
236 
237 	for (size_t i = 0; i < num_fragments; i++) {
238 		if ((total_len > *result_len)
239 			|| (fragments[i].fragment.len > (*result_len - total_len))) {
240 			return false;
241 		}
242 		memcpy(&result[total_len],
243 			fragments[i].fragment.value, fragments[i].fragment.len);
244 		total_len += fragments[i].fragment.len;
245 	}
246 
247 	*result_len = total_len;
248 	return true;
249 }
250 
251 
zcbor_compare_strings(const struct zcbor_string * str1,const struct zcbor_string * str2)252 bool zcbor_compare_strings(const struct zcbor_string *str1,
253 		const struct zcbor_string *str2)
254 {
255 	return (str1 != NULL) && (str2 != NULL)
256 		&& (str1->value != NULL) && (str2->value != NULL) && (str1->len == str2->len)
257 		&& (memcmp(str1->value, str2->value, str1->len) == 0);
258 }
259 
260 
zcbor_header_len(uint64_t value)261 size_t zcbor_header_len(uint64_t value)
262 {
263 	if (value <= ZCBOR_VALUE_IN_HEADER) {
264 		return 1;
265 	} else if (value <= 0xFF) {
266 		return 2;
267 	} else if (value <= 0xFFFF) {
268 		return 3;
269 	} else if (value <= 0xFFFFFFFF) {
270 		return 5;
271 	} else {
272 		return 9;
273 	}
274 }
275 
276 
zcbor_header_len_ptr(const void * const value,size_t value_len)277 size_t zcbor_header_len_ptr(const void *const value, size_t value_len)
278 {
279 	uint64_t val64 = 0;
280 
281 	if (value_len > sizeof(val64)) {
282 		return 0;
283 	}
284 
285 	memcpy(((uint8_t*)&val64) + ZCBOR_ECPY_OFFS(sizeof(val64), value_len), value, value_len);
286 	return zcbor_header_len(val64);
287 }
288 
289 
zcbor_entry_function(const uint8_t * payload,size_t payload_len,void * result,size_t * payload_len_out,zcbor_state_t * state,zcbor_decoder_t func,size_t n_states,size_t elem_count)290 int zcbor_entry_function(const uint8_t *payload, size_t payload_len,
291 	void *result, size_t *payload_len_out, zcbor_state_t *state, zcbor_decoder_t func,
292 	size_t n_states, size_t elem_count)
293 {
294 	zcbor_new_state(state, n_states, payload, payload_len, elem_count, NULL, 0);
295 
296 	bool ret = func(state, result);
297 
298 	if (!ret) {
299 		int err = zcbor_pop_error(state);
300 
301 		err = (err == ZCBOR_SUCCESS) ? ZCBOR_ERR_UNKNOWN : err;
302 		return err;
303 	}
304 
305 	if (payload_len_out != NULL) {
306 		*payload_len_out = MIN(payload_len,
307 				(size_t)state[0].payload - (size_t)payload);
308 	}
309 	return ZCBOR_SUCCESS;
310 }
311 
312 
313 /* Float16: */
314 #define F16_SIGN_OFFS 15 /* Bit offset of the sign bit. */
315 #define F16_EXPO_OFFS 10 /* Bit offset of the exponent. */
316 #define F16_EXPO_MSK 0x1F /* Bitmask for the exponent (right shifted by F16_EXPO_OFFS). */
317 #define F16_MANTISSA_MSK 0x3FF /* Bitmask for the mantissa. */
318 #define F16_MAX 65520 /* Lowest float32 value that rounds up to float16 infinity.
319 		       * (65519.996 rounds to 65504) */
320 #define F16_MIN_EXPO 24 /* Negative exponent of the non-zero float16 value closest to 0 (2^-24) */
321 #define F16_MIN (1.0f / (1 << F16_MIN_EXPO)) /* The non-zero float16 value closest to 0 (2^-24) */
322 #define F16_MIN_NORM (1.0f / (1 << 14)) /* The normalized float16 value closest to 0 (2^-14) */
323 #define F16_BIAS 15 /* The exponent bias of normalized float16 values. */
324 
325 /* Float32: */
326 #define F32_SIGN_OFFS 31 /* Bit offset of the sign bit. */
327 #define F32_EXPO_OFFS 23 /* Bit offset of the exponent. */
328 #define F32_EXPO_MSK 0xFF /* Bitmask for the exponent (right shifted by F32_EXPO_OFFS). */
329 #define F32_MANTISSA_MSK 0x7FFFFF /* Bitmask for the mantissa. */
330 #define F32_BIAS 127 /* The exponent bias of normalized float32 values. */
331 
332 /* Rounding: */
333 #define SUBNORM_ROUND_MSK (F32_MANTISSA_MSK | (1 << F32_EXPO_OFFS)) /* mantissa + lsb of expo for
334 								     * tiebreak. */
335 #define SUBNORM_ROUND_BIT_MSK (1 << (F32_EXPO_OFFS - 1)) /* msb of mantissa (0x400000) */
336 #define NORM_ROUND_MSK (F32_MANTISSA_MSK >> (F16_EXPO_OFFS - 1)) /* excess mantissa when going from
337 								  * float32 to float16 + 1 extra bit
338 								  * for tiebreak. */
339 #define NORM_ROUND_BIT_MSK (1 << (F32_EXPO_OFFS - F16_EXPO_OFFS - 1)) /* bit 12 (0x1000) */
340 
341 
zcbor_float16_to_32(uint16_t input)342 float zcbor_float16_to_32(uint16_t input)
343 {
344 	uint32_t sign = input >> F16_SIGN_OFFS;
345 	uint32_t expo = (input >> F16_EXPO_OFFS) & F16_EXPO_MSK;
346 	uint32_t mantissa = input & F16_MANTISSA_MSK;
347 
348 	if ((expo == 0) && (mantissa != 0)) {
349 		/* Subnormal float16 - convert to normalized float32 */
350 		return ((float)mantissa * F16_MIN) * (sign ? -1 : 1);
351 	} else {
352 		/* Normalized / zero / Infinity / NaN */
353 		uint32_t new_expo = (expo == 0 /* zero */) ? 0
354 			: (expo == F16_EXPO_MSK /* inf/NaN */) ? F32_EXPO_MSK
355 				: (expo + (F32_BIAS - F16_BIAS));
356 		uint32_t value32 = (sign << F32_SIGN_OFFS) | (new_expo << F32_EXPO_OFFS)
357 			| (mantissa << (F32_EXPO_OFFS - F16_EXPO_OFFS));
358 		float result;
359 
360 		memcpy(&result, &value32, sizeof(result));
361 		return result;
362 	}
363 }
364 
365 
zcbor_float32_to_16(float input)366 uint16_t zcbor_float32_to_16(float input)
367 {
368 	uint32_t value32;
369 
370 	memcpy(&value32, &input, sizeof(value32));
371 
372 	uint32_t sign = value32 >> F32_SIGN_OFFS;
373 	uint32_t expo = (value32 >> F32_EXPO_OFFS) & F32_EXPO_MSK;
374 	uint32_t mantissa = value32 & F32_MANTISSA_MSK;
375 
376 	uint16_t value16 = (uint16_t)(sign << F16_SIGN_OFFS);
377 
378 	uint32_t abs_value32 = value32 & ~(1 << F32_SIGN_OFFS);
379 	float abs_input;
380 
381 	memcpy(&abs_input, &abs_value32, sizeof(abs_input));
382 
383 	if (abs_input <= (F16_MIN / 2)) {
384 		/* 0 or too small for float16. Round down to 0. value16 is already correct. */
385 	} else if (abs_input < F16_MIN) {
386 		/* Round up to 2^(-24) (F16_MIN), has other rounding rules than larger values. */
387 		value16 |= 0x0001;
388 	} else if (abs_input < F16_MIN_NORM) {
389 		/* Subnormal float16 (normal float32) */
390 		uint32_t adjusted_mantissa =
391 			/* Adjust for the purposes of checking rounding. */
392 			/* The lsb of expo is needed for the cases where expo is 103 (minimum). */
393 			((value32 << (expo - (F32_BIAS - F16_MIN_EXPO))) & SUBNORM_ROUND_MSK);
394 		uint16_t rounding_bit =
395 			/* "Round to nearest, ties to even". */
396 			/* 0x400000 means ties go down towards even. (0xC00000 means ties go up.) */
397 			(adjusted_mantissa & SUBNORM_ROUND_BIT_MSK)
398 				&& (adjusted_mantissa != SUBNORM_ROUND_BIT_MSK);
399 		value16 |= ((uint16_t)(abs_input * (1 << 24)) + rounding_bit); /* expo is 0 */
400 	} else if (abs_input < F16_MAX) {
401 		/* Normal float16 (normal float32) */
402 		uint16_t rounding_bit =
403 			/* Bit 13 of the mantissa represents which way to round, except for the */
404 			/* special case where bits 0-12 and 14 are 0. */
405 			/* This is because of "Round to nearest, ties to even". */
406 			/* 0x1000 means ties go down towards even. (0x3000 means ties go up.) */
407 			((mantissa & NORM_ROUND_BIT_MSK)
408 				&& ((mantissa & NORM_ROUND_MSK) != NORM_ROUND_BIT_MSK));
409 		value16 |= (uint16_t)((expo - (F32_BIAS - F16_BIAS)) << F16_EXPO_OFFS);
410 		value16 |= (uint16_t)(mantissa >> (F32_EXPO_OFFS - F16_EXPO_OFFS));
411 		value16 += rounding_bit; /* Might propagate to exponent. */
412 	} else if (expo != F32_EXPO_MSK || !mantissa) {
413 		/* Infinite, or finite normal float32 too large for float16. Round up to inf. */
414 		value16 |= (F16_EXPO_MSK << F16_EXPO_OFFS);
415 	} else {
416 		/* NaN */
417 		/* Preserve msbit of mantissa. */
418 		uint16_t new_mantissa = (uint16_t)(mantissa >> (F32_EXPO_OFFS - F16_EXPO_OFFS));
419 		value16 |= (F16_EXPO_MSK << F16_EXPO_OFFS) | (new_mantissa ? new_mantissa : 1);
420 	}
421 
422 	return value16;
423 }
424 
425 
426 /** Weak strnlen() implementation in case it is not available.
427  *
428  * This function is in the public domain, according to:
429  * https://github.com/arm-embedded/gcc-arm-none-eabi.debian/blob/master/src/libiberty/strnlen.c
430  */
431 __attribute__((__weak__))
strnlen(const char * s,size_t maxlen)432 size_t strnlen (const char *s, size_t maxlen)
433 {
434 	size_t i;
435 
436 	for (i = 0; i < maxlen; ++i) {
437 		if (s[i] == '\0') {
438 			break;
439 		}
440 	}
441 	return i;
442 }
443