xref: /aosp_15_r20/external/avb/libavb/avb_util.h (revision d289c2ba6de359471b23d594623b906876bc48a0)
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Permission is hereby granted, free of charge, to any person
5  * obtaining a copy of this software and associated documentation
6  * files (the "Software"), to deal in the Software without
7  * restriction, including without limitation the rights to use, copy,
8  * modify, merge, publish, distribute, sublicense, and/or sell copies
9  * 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
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 
25 #if !defined(AVB_INSIDE_LIBAVB_H) && !defined(AVB_COMPILATION)
26 #error "Never include this file directly, include libavb.h instead."
27 #endif
28 
29 #ifndef AVB_UTIL_H_
30 #define AVB_UTIL_H_
31 
32 #include "avb_sysdeps.h"
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 #define AVB_CONCAT(x, y) x##y
39 #define AVB_STRINGIFY(x) #x
40 #define AVB_TO_STRING(x) AVB_STRINGIFY(x)
41 
42 #define AVB__COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, x, ...) x
43 #define AVB_COUNT_ARGS(...) \
44   AVB__COUNT_ARGS(, ##__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0)
45 
46 #define AVB__REPEAT0(x)
47 #define AVB__REPEAT1(x) x
48 #define AVB__REPEAT2(x) AVB__REPEAT1(x) x
49 #define AVB__REPEAT3(x) AVB__REPEAT2(x) x
50 #define AVB__REPEAT4(x) AVB__REPEAT3(x) x
51 #define AVB__REPEAT5(x) AVB__REPEAT4(x) x
52 #define AVB__REPEAT6(x) AVB__REPEAT5(x) x
53 #define AVB__REPEAT7(x) AVB__REPEAT6(x) x
54 #define AVB__REPEAT(n, x) AVB_CONCAT(AVB__REPEAT, n)(x)
55 #define AVB_REPEAT(n, x) AVB__REPEAT(n, x)
56 
57 #ifdef AVB_USE_PRINTF_LOGS
58 #define AVB_LOG(level, message, ...)                                        \
59   avb_printf("%s:%d: " level                                                \
60              ": " AVB_REPEAT(AVB_COUNT_ARGS(message, ##__VA_ARGS__), "%s"), \
61              avb_basename(__FILE__),                                        \
62              __LINE__,                                                      \
63              message,                                                       \
64              ##__VA_ARGS__)
65 #else
66 #define AVB_LOG(level, message, ...)  \
67   avb_printv(avb_basename(__FILE__),  \
68              ":",                     \
69              AVB_TO_STRING(__LINE__), \
70              ": " level ": ",         \
71              message,                 \
72              ##__VA_ARGS__,           \
73              NULL)
74 #endif
75 
76 #ifdef AVB_ENABLE_DEBUG
77 /* Aborts the program if |expr| is false.
78  *
79  * This has no effect unless AVB_ENABLE_DEBUG is defined.
80  */
81 #define avb_assert(expr)                     \
82   do {                                       \
83     if (!(expr)) {                           \
84       avb_fatal("assert fail: " #expr "\n"); \
85     }                                        \
86   } while (0)
87 
88 /* Aborts the program if reached.
89  *
90  * This has no effect unless AVB_ENABLE_DEBUG is defined.
91  */
92 #define avb_assert_not_reached()         \
93   do {                                   \
94     avb_fatal("assert_not_reached()\n"); \
95   } while (0)
96 
97 /* Print functions, used for diagnostics.
98  *
99  * These have no effect unless AVB_ENABLE_DEBUG is defined.
100  */
101 #define avb_debug(message, ...)               \
102   do {                                        \
103     AVB_LOG("DEBUG", message, ##__VA_ARGS__); \
104   } while (0)
105 #else
106 #define avb_assert(expr)
107 #define avb_assert_not_reached()
108 #define avb_debug(message, ...)
109 #endif
110 
111 /* Aborts the program if |addr| is not word-aligned.
112  *
113  * This has no effect unless AVB_ENABLE_DEBUG is defined.
114  */
115 #define avb_assert_aligned(addr) \
116   avb_assert((((uintptr_t)addr) & (AVB_ALIGNMENT_SIZE - 1)) == 0)
117 
118 /* Prints out a message. This is typically used if a runtime-error
119  * occurs.
120  */
121 #define avb_error(message, ...)               \
122   do {                                        \
123     AVB_LOG("ERROR", message, ##__VA_ARGS__); \
124   } while (0)
125 
126 /* Prints out a message and calls avb_abort().
127  */
128 #define avb_fatal(message, ...)               \
129   do {                                        \
130     AVB_LOG("FATAL", message, ##__VA_ARGS__); \
131     avb_abort();                              \
132   } while (0)
133 
134 #ifndef AVB_USE_PRINTF_LOGS
135 /* Deprecated legacy logging functions -- kept for client compatibility.
136  */
137 #define avb_debugv(message, ...) avb_debug(message, ##__VA_ARGS__)
138 #define avb_errorv(message, ...) avb_error(message, ##__VA_ARGS__)
139 #define avb_fatalv(message, ...) avb_fatal(message, ##__VA_ARGS__)
140 #endif
141 
142 /* Converts a 16-bit unsigned integer from big-endian to host byte order. */
143 uint16_t avb_be16toh(uint16_t in) AVB_ATTR_WARN_UNUSED_RESULT;
144 
145 /* Converts a 32-bit unsigned integer from big-endian to host byte order. */
146 uint32_t avb_be32toh(uint32_t in) AVB_ATTR_WARN_UNUSED_RESULT;
147 
148 /* Converts a 64-bit unsigned integer from big-endian to host byte order. */
149 uint64_t avb_be64toh(uint64_t in) AVB_ATTR_WARN_UNUSED_RESULT;
150 
151 /* Converts a 16-bit unsigned integer from host to big-endian byte order. */
152 uint16_t avb_htobe16(uint16_t in) AVB_ATTR_WARN_UNUSED_RESULT;
153 
154 /* Converts a 32-bit unsigned integer from host to big-endian byte order. */
155 uint32_t avb_htobe32(uint32_t in) AVB_ATTR_WARN_UNUSED_RESULT;
156 
157 /* Converts a 64-bit unsigned integer from host to big-endian byte order. */
158 uint64_t avb_htobe64(uint64_t in) AVB_ATTR_WARN_UNUSED_RESULT;
159 
160 /* Compare |n| bytes starting at |s1| with |s2| and return 0 if they
161  * match, 1 if they don't.  Returns 0 if |n|==0, since no bytes
162  * mismatched.
163  *
164  * Time taken to perform the comparison is only dependent on |n| and
165  * not on the relationship of the match between |s1| and |s2|.
166  *
167  * Note that unlike avb_memcmp(), this only indicates inequality, not
168  * whether |s1| is less than or greater than |s2|.
169  */
170 int avb_safe_memcmp(const void* s1,
171                     const void* s2,
172                     size_t n) AVB_ATTR_WARN_UNUSED_RESULT;
173 
174 /* Adds |value_to_add| to |value| with overflow protection.
175  *
176  * Returns false if the addition overflows, true otherwise. In either
177  * case, |value| is always modified.
178  */
179 bool avb_safe_add_to(uint64_t* value,
180                      uint64_t value_to_add) AVB_ATTR_WARN_UNUSED_RESULT;
181 
182 /* Adds |a| and |b| with overflow protection, returning the value in
183  * |out_result|.
184  *
185  * It's permissible to pass NULL for |out_result| if you just want to
186  * check that the addition would not overflow.
187  *
188  * Returns false if the addition overflows, true otherwise.
189  */
190 bool avb_safe_add(uint64_t* out_result,
191                   uint64_t a,
192                   uint64_t b) AVB_ATTR_WARN_UNUSED_RESULT;
193 
194 /* Checks if |num_bytes| data at |data| is a valid UTF-8
195  * string. Returns true if valid UTF-8, false otherwise.
196  */
197 bool avb_validate_utf8(const uint8_t* data,
198                        size_t num_bytes) AVB_ATTR_WARN_UNUSED_RESULT;
199 
200 /* Concatenates |str1| (of |str1_len| bytes) and |str2| (of |str2_len|
201  * bytes) and puts the result in |buf| which holds |buf_size|
202  * bytes. The result is also guaranteed to be NUL terminated. Fail if
203  * there is not enough room in |buf| for the resulting string plus
204  * terminating NUL byte.
205  *
206  * Returns true if the operation succeeds, false otherwise.
207  */
208 bool avb_str_concat(char* buf,
209                     size_t buf_size,
210                     const char* str1,
211                     size_t str1_len,
212                     const char* str2,
213                     size_t str2_len);
214 
215 /* Like avb_malloc_() but prints a error using avb_error() if memory
216  * allocation fails.
217  */
218 void* avb_malloc(size_t size) AVB_ATTR_WARN_UNUSED_RESULT;
219 
220 /* Like avb_malloc() but sets the memory with zeroes. */
221 void* avb_calloc(size_t size) AVB_ATTR_WARN_UNUSED_RESULT;
222 
223 /* Duplicates a NUL-terminated string. Returns NULL on OOM. */
224 char* avb_strdup(const char* str) AVB_ATTR_WARN_UNUSED_RESULT;
225 
226 /* Duplicates a NULL-terminated array of NUL-terminated strings by
227  * concatenating them. The returned string will be
228  * NUL-terminated. Returns NULL on OOM.
229  */
230 char* avb_strdupv(const char* str,
231                   ...) AVB_ATTR_WARN_UNUSED_RESULT AVB_ATTR_SENTINEL;
232 
233 /* Finds the first occurrence of |needle| in the string |haystack|
234  * where both strings are NUL-terminated strings. The terminating NUL
235  * bytes are not compared.
236  *
237  * Returns NULL if not found, otherwise points into |haystack| for the
238  * first occurrence of |needle|.
239  */
240 const char* avb_strstr(const char* haystack,
241                        const char* needle) AVB_ATTR_WARN_UNUSED_RESULT;
242 
243 /* Finds the first occurrence of |str| in the NULL-terminated string
244  * array |strings|. Each element in |strings| must be
245  * NUL-terminated. The string given by |str| need not be
246  * NUL-terminated but its size must be given in |str_size|.
247  *
248  * Returns NULL if not found, otherwise points into |strings| for the
249  * first occurrence of |str|.
250  */
251 const char* avb_strv_find_str(const char* const* strings,
252                               const char* str,
253                               size_t str_size);
254 
255 /* Replaces all occurrences of |search| with |replace| in |str|.
256  *
257  * Returns a newly allocated string or NULL if out of memory.
258  */
259 char* avb_replace(const char* str,
260                   const char* search,
261                   const char* replace) AVB_ATTR_WARN_UNUSED_RESULT;
262 
263 /* Calculates the CRC-32 for data in |buf| of size |buf_size|. */
264 uint32_t avb_crc32(const uint8_t* buf, size_t buf_size);
265 
266 /* Returns the basename of |str|. This is defined as the last path
267  * component, assuming the normal POSIX separator '/'. If there are no
268  * separators, returns |str|.
269  */
270 const char* avb_basename(const char* str);
271 
272 /* Converts any ascii lowercase characters in |str| to uppercase in-place.
273  * |str| must be NUL-terminated and valid UTF-8.
274  */
275 void avb_uppercase(char* str);
276 
277 /* Converts |data_len| bytes of |data| to hex and returns the result. Returns
278  * NULL on OOM. Caller must free the returned string with avb_free.
279  */
280 char* avb_bin2hex(const uint8_t* data, size_t data_len);
281 
282 /* Writes |value| to |digits| in base 10 followed by a NUL byte.
283  * Returns number of characters written excluding the NUL byte.
284  */
285 #define AVB_MAX_DIGITS_UINT64 32
286 size_t avb_uint64_to_base10(uint64_t value, char digits[AVB_MAX_DIGITS_UINT64]);
287 #ifdef __cplusplus
288 }
289 #endif
290 
291 #endif /* AVB_UTIL_H_ */
292