1/* SPDX-License-Identifier: MIT */
2/*
3 * Copyright (C) 2016 The Android Open Source Project
4 */
5
6#if !defined(AVB_INSIDE_LIBAVB_H) && !defined(AVB_COMPILATION)
7#error "Never include this file directly, include libavb.h instead."
8#endif
9
10#ifndef AVB_UTIL_H_
11#define AVB_UTIL_H_
12
13#include "avb_sysdeps.h"
14
15#ifdef __cplusplus
16extern "C" {
17#endif
18
19#define AVB_STRINGIFY(x) #x
20#define AVB_TO_STRING(x) AVB_STRINGIFY(x)
21
22#ifdef AVB_ENABLE_DEBUG
23/* Aborts the program if |expr| is false.
24 *
25 * This has no effect unless AVB_ENABLE_DEBUG is defined.
26 */
27#define avb_assert(expr)                     \
28  do {                                       \
29    if (!(expr)) {                           \
30      avb_fatal("assert fail: " #expr "\n"); \
31    }                                        \
32  } while (0)
33#else
34#define avb_assert(expr)
35#endif
36
37/* Aborts the program if reached.
38 *
39 * This has no effect unless AVB_ENABLE_DEBUG is defined.
40 */
41#ifdef AVB_ENABLE_DEBUG
42#define avb_assert_not_reached()         \
43  do {                                   \
44    avb_fatal("assert_not_reached()\n"); \
45  } while (0)
46#else
47#define avb_assert_not_reached()
48#endif
49
50/* Aborts the program if |addr| is not word-aligned.
51 *
52 * This has no effect unless AVB_ENABLE_DEBUG is defined.
53 */
54#define avb_assert_aligned(addr) \
55  avb_assert((((uintptr_t)addr) & (AVB_ALIGNMENT_SIZE - 1)) == 0)
56
57#ifdef AVB_ENABLE_DEBUG
58/* Print functions, used for diagnostics.
59 *
60 * These have no effect unless AVB_ENABLE_DEBUG is defined.
61 */
62#define avb_debug(message)              \
63  do {                                  \
64    avb_printv(avb_basename(__FILE__),  \
65               ":",                     \
66               AVB_TO_STRING(__LINE__), \
67               ": DEBUG: ",             \
68               message,                 \
69               NULL);                   \
70  } while (0)
71#define avb_debugv(message, ...)        \
72  do {                                  \
73    avb_printv(avb_basename(__FILE__),  \
74               ":",                     \
75               AVB_TO_STRING(__LINE__), \
76               ": DEBUG: ",             \
77               message,                 \
78               ##__VA_ARGS__);          \
79  } while (0)
80#else
81#define avb_debug(message)
82#define avb_debugv(message, ...)
83#endif
84
85/* Prints out a message. This is typically used if a runtime-error
86 * occurs.
87 */
88#define avb_error(message)              \
89  do {                                  \
90    avb_printv(avb_basename(__FILE__),  \
91               ":",                     \
92               AVB_TO_STRING(__LINE__), \
93               ": ERROR: ",             \
94               message,                 \
95               NULL);                   \
96  } while (0)
97#define avb_errorv(message, ...)        \
98  do {                                  \
99    avb_printv(avb_basename(__FILE__),  \
100               ":",                     \
101               AVB_TO_STRING(__LINE__), \
102               ": ERROR: ",             \
103               message,                 \
104               ##__VA_ARGS__);          \
105  } while (0)
106
107/* Prints out a message and calls avb_abort().
108 */
109#define avb_fatal(message)              \
110  do {                                  \
111    avb_printv(avb_basename(__FILE__),  \
112               ":",                     \
113               AVB_TO_STRING(__LINE__), \
114               ": FATAL: ",             \
115               message,                 \
116               NULL);                   \
117    avb_abort();                        \
118  } while (0)
119#define avb_fatalv(message, ...)        \
120  do {                                  \
121    avb_printv(avb_basename(__FILE__),  \
122               ":",                     \
123               AVB_TO_STRING(__LINE__), \
124               ": FATAL: ",             \
125               message,                 \
126               ##__VA_ARGS__);          \
127    avb_abort();                        \
128  } while (0)
129
130/* Converts a 32-bit unsigned integer from big-endian to host byte order. */
131uint32_t avb_be32toh(uint32_t in) AVB_ATTR_WARN_UNUSED_RESULT;
132
133/* Converts a 64-bit unsigned integer from big-endian to host byte order. */
134uint64_t avb_be64toh(uint64_t in) AVB_ATTR_WARN_UNUSED_RESULT;
135
136/* Converts a 32-bit unsigned integer from host to big-endian byte order. */
137uint32_t avb_htobe32(uint32_t in) AVB_ATTR_WARN_UNUSED_RESULT;
138
139/* Converts a 64-bit unsigned integer from host to big-endian byte order. */
140uint64_t avb_htobe64(uint64_t in) AVB_ATTR_WARN_UNUSED_RESULT;
141
142/* Compare |n| bytes starting at |s1| with |s2| and return 0 if they
143 * match, 1 if they don't.  Returns 0 if |n|==0, since no bytes
144 * mismatched.
145 *
146 * Time taken to perform the comparison is only dependent on |n| and
147 * not on the relationship of the match between |s1| and |s2|.
148 *
149 * Note that unlike avb_memcmp(), this only indicates inequality, not
150 * whether |s1| is less than or greater than |s2|.
151 */
152int avb_safe_memcmp(const void* s1,
153                    const void* s2,
154                    size_t n) AVB_ATTR_WARN_UNUSED_RESULT;
155
156/* Adds |value_to_add| to |value| with overflow protection.
157 *
158 * Returns false if the addition overflows, true otherwise. In either
159 * case, |value| is always modified.
160 */
161bool avb_safe_add_to(uint64_t* value,
162                     uint64_t value_to_add) AVB_ATTR_WARN_UNUSED_RESULT;
163
164/* Adds |a| and |b| with overflow protection, returning the value in
165 * |out_result|.
166 *
167 * It's permissible to pass NULL for |out_result| if you just want to
168 * check that the addition would not overflow.
169 *
170 * Returns false if the addition overflows, true otherwise.
171 */
172bool avb_safe_add(uint64_t* out_result,
173                  uint64_t a,
174                  uint64_t b) AVB_ATTR_WARN_UNUSED_RESULT;
175
176/* Checks if |num_bytes| data at |data| is a valid UTF-8
177 * string. Returns true if valid UTF-8, false otherwise.
178 */
179bool avb_validate_utf8(const uint8_t* data,
180                       size_t num_bytes) AVB_ATTR_WARN_UNUSED_RESULT;
181
182/* Concatenates |str1| (of |str1_len| bytes) and |str2| (of |str2_len|
183 * bytes) and puts the result in |buf| which holds |buf_size|
184 * bytes. The result is also guaranteed to be NUL terminated. Fail if
185 * there is not enough room in |buf| for the resulting string plus
186 * terminating NUL byte.
187 *
188 * Returns true if the operation succeeds, false otherwise.
189 */
190bool avb_str_concat(char* buf,
191                    size_t buf_size,
192                    const char* str1,
193                    size_t str1_len,
194                    const char* str2,
195                    size_t str2_len);
196
197/* Like avb_malloc_() but prints a error using avb_error() if memory
198 * allocation fails.
199 */
200void* avb_malloc(size_t size) AVB_ATTR_WARN_UNUSED_RESULT;
201
202/* Like avb_malloc() but sets the memory with zeroes. */
203void* avb_calloc(size_t size) AVB_ATTR_WARN_UNUSED_RESULT;
204
205/* Duplicates a NUL-terminated string. Returns NULL on OOM. */
206char* avb_strdup(const char* str) AVB_ATTR_WARN_UNUSED_RESULT;
207
208/* Duplicates a NULL-terminated array of NUL-terminated strings by
209 * concatenating them. The returned string will be
210 * NUL-terminated. Returns NULL on OOM.
211 */
212char* avb_strdupv(const char* str,
213                  ...) AVB_ATTR_WARN_UNUSED_RESULT AVB_ATTR_SENTINEL;
214
215/* Finds the first occurrence of |needle| in the string |haystack|
216 * where both strings are NUL-terminated strings. The terminating NUL
217 * bytes are not compared.
218 *
219 * Returns NULL if not found, otherwise points into |haystack| for the
220 * first occurrence of |needle|.
221 */
222const char* avb_strstr(const char* haystack,
223                       const char* needle) AVB_ATTR_WARN_UNUSED_RESULT;
224
225/* Finds the first occurrence of |str| in the NULL-terminated string
226 * array |strings|. Each element in |strings| must be
227 * NUL-terminated. The string given by |str| need not be
228 * NUL-terminated but its size must be given in |str_size|.
229 *
230 * Returns NULL if not found, otherwise points into |strings| for the
231 * first occurrence of |str|.
232 */
233const char* avb_strv_find_str(const char* const* strings,
234                              const char* str,
235                              size_t str_size);
236
237/* Replaces all occurrences of |search| with |replace| in |str|.
238 *
239 * Returns a newly allocated string or NULL if out of memory.
240 */
241char* avb_replace(const char* str,
242                  const char* search,
243                  const char* replace) AVB_ATTR_WARN_UNUSED_RESULT;
244
245/* Calculates the CRC-32 for data in |buf| of size |buf_size|. */
246uint32_t avb_crc32(const uint8_t* buf, size_t buf_size);
247
248/* Returns the basename of |str|. This is defined as the last path
249 * component, assuming the normal POSIX separator '/'. If there are no
250 * separators, returns |str|.
251 */
252const char* avb_basename(const char* str);
253
254/* Converts any ascii lowercase characters in |str| to uppercase in-place.
255 * |str| must be NUL-terminated and valid UTF-8.
256 */
257void avb_uppercase(char* str);
258
259/* Converts |data_len| bytes of |data| to hex and returns the result. Returns
260 * NULL on OOM. Caller must free the returned string with avb_free.
261 */
262char* avb_bin2hex(const uint8_t* data, size_t data_len);
263
264#ifdef __cplusplus
265}
266#endif
267
268#endif /* AVB_UTIL_H_ */
269