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 #include "avb_util.h" 26 27 #include <stdarg.h> 28 29 uint32_t avb_be32toh(uint32_t in) { 30 uint8_t* d = (uint8_t*)∈ 31 uint32_t ret; 32 ret = ((uint32_t)d[0]) << 24; 33 ret |= ((uint32_t)d[1]) << 16; 34 ret |= ((uint32_t)d[2]) << 8; 35 ret |= ((uint32_t)d[3]); 36 return ret; 37 } 38 39 uint64_t avb_be64toh(uint64_t in) { 40 uint8_t* d = (uint8_t*)∈ 41 uint64_t ret; 42 ret = ((uint64_t)d[0]) << 56; 43 ret |= ((uint64_t)d[1]) << 48; 44 ret |= ((uint64_t)d[2]) << 40; 45 ret |= ((uint64_t)d[3]) << 32; 46 ret |= ((uint64_t)d[4]) << 24; 47 ret |= ((uint64_t)d[5]) << 16; 48 ret |= ((uint64_t)d[6]) << 8; 49 ret |= ((uint64_t)d[7]); 50 return ret; 51 } 52 53 /* Converts a 32-bit unsigned integer from host to big-endian byte order. */ 54 uint32_t avb_htobe32(uint32_t in) { 55 union { 56 uint32_t word; 57 uint8_t bytes[4]; 58 } ret; 59 ret.bytes[0] = (in >> 24) & 0xff; 60 ret.bytes[1] = (in >> 16) & 0xff; 61 ret.bytes[2] = (in >> 8) & 0xff; 62 ret.bytes[3] = in & 0xff; 63 return ret.word; 64 } 65 66 /* Converts a 64-bit unsigned integer from host to big-endian byte order. */ 67 uint64_t avb_htobe64(uint64_t in) { 68 union { 69 uint64_t word; 70 uint8_t bytes[8]; 71 } ret; 72 ret.bytes[0] = (in >> 56) & 0xff; 73 ret.bytes[1] = (in >> 48) & 0xff; 74 ret.bytes[2] = (in >> 40) & 0xff; 75 ret.bytes[3] = (in >> 32) & 0xff; 76 ret.bytes[4] = (in >> 24) & 0xff; 77 ret.bytes[5] = (in >> 16) & 0xff; 78 ret.bytes[6] = (in >> 8) & 0xff; 79 ret.bytes[7] = in & 0xff; 80 return ret.word; 81 } 82 83 int avb_safe_memcmp(const void* s1, const void* s2, size_t n) { 84 const unsigned char* us1 = s1; 85 const unsigned char* us2 = s2; 86 int result = 0; 87 88 if (0 == n) { 89 return 0; 90 } 91 92 /* 93 * Code snippet without data-dependent branch due to Nate Lawson 94 * (nate (at) root.org) of Root Labs. 95 */ 96 while (n--) { 97 result |= *us1++ ^ *us2++; 98 } 99 100 return result != 0; 101 } 102 103 bool avb_safe_add_to(uint64_t* value, uint64_t value_to_add) { 104 uint64_t original_value; 105 106 avb_assert(value != NULL); 107 108 original_value = *value; 109 110 *value += value_to_add; 111 if (*value < original_value) { 112 avb_error("Overflow when adding values.\n"); 113 return false; 114 } 115 116 return true; 117 } 118 119 bool avb_safe_add(uint64_t* out_result, uint64_t a, uint64_t b) { 120 uint64_t dummy; 121 if (out_result == NULL) { 122 out_result = &dummy; 123 } 124 *out_result = a; 125 return avb_safe_add_to(out_result, b); 126 } 127 128 bool avb_validate_utf8(const uint8_t* data, size_t num_bytes) { 129 size_t n; 130 unsigned int num_cc; 131 132 for (n = 0, num_cc = 0; n < num_bytes; n++) { 133 uint8_t c = data[n]; 134 135 if (num_cc > 0) { 136 if ((c & (0x80 | 0x40)) == 0x80) { 137 /* 10xx xxxx */ 138 } else { 139 goto fail; 140 } 141 num_cc--; 142 } else { 143 if (c < 0x80) { 144 num_cc = 0; 145 } else if ((c & (0x80 | 0x40 | 0x20)) == (0x80 | 0x40)) { 146 /* 110x xxxx */ 147 num_cc = 1; 148 } else if ((c & (0x80 | 0x40 | 0x20 | 0x10)) == (0x80 | 0x40 | 0x20)) { 149 /* 1110 xxxx */ 150 num_cc = 2; 151 } else if ((c & (0x80 | 0x40 | 0x20 | 0x10 | 0x08)) == 152 (0x80 | 0x40 | 0x20 | 0x10)) { 153 /* 1111 0xxx */ 154 num_cc = 3; 155 } else { 156 goto fail; 157 } 158 } 159 } 160 161 if (num_cc != 0) { 162 goto fail; 163 } 164 165 return true; 166 167 fail: 168 return false; 169 } 170 171 bool avb_str_concat(char* buf, 172 size_t buf_size, 173 const char* str1, 174 size_t str1_len, 175 const char* str2, 176 size_t str2_len) { 177 uint64_t combined_len; 178 179 if (!avb_safe_add(&combined_len, str1_len, str2_len)) { 180 avb_error("Overflow when adding string sizes.\n"); 181 return false; 182 } 183 184 if (combined_len > buf_size - 1) { 185 avb_error("Insufficient buffer space.\n"); 186 return false; 187 } 188 189 avb_memcpy(buf, str1, str1_len); 190 avb_memcpy(buf + str1_len, str2, str2_len); 191 buf[combined_len] = '\0'; 192 193 return true; 194 } 195 196 void* avb_malloc(size_t size) { 197 void* ret = avb_malloc_(size); 198 if (ret == NULL) { 199 avb_error("Failed to allocate memory.\n"); 200 return NULL; 201 } 202 return ret; 203 } 204 205 void* avb_calloc(size_t size) { 206 void* ret = avb_malloc(size); 207 if (ret == NULL) { 208 return NULL; 209 } 210 211 avb_memset(ret, '\0', size); 212 return ret; 213 } 214 215 char* avb_strdup(const char* str) { 216 size_t len = avb_strlen(str); 217 char* ret = avb_malloc(len + 1); 218 if (ret == NULL) { 219 return NULL; 220 } 221 222 avb_memcpy(ret, str, len); 223 ret[len] = '\0'; 224 225 return ret; 226 } 227 228 const char* avb_strstr(const char* haystack, const char* needle) { 229 size_t n, m; 230 231 /* Look through |haystack| and check if the first character of 232 * |needle| matches. If so, check the rest of |needle|. 233 */ 234 for (n = 0; haystack[n] != '\0'; n++) { 235 if (haystack[n] != needle[0]) { 236 continue; 237 } 238 239 for (m = 1;; m++) { 240 if (needle[m] == '\0') { 241 return haystack + n; 242 } 243 244 if (haystack[n + m] != needle[m]) { 245 break; 246 } 247 } 248 } 249 250 return NULL; 251 } 252 253 const char* avb_strv_find_str(const char* const* strings, 254 const char* str, 255 size_t str_size) { 256 size_t n; 257 for (n = 0; strings[n] != NULL; n++) { 258 if (avb_strlen(strings[n]) == str_size && 259 avb_memcmp(strings[n], str, str_size) == 0) { 260 return strings[n]; 261 } 262 } 263 return NULL; 264 } 265 266 char* avb_replace(const char* str, const char* search, const char* replace) { 267 char* ret = NULL; 268 size_t ret_len = 0; 269 size_t search_len, replace_len; 270 const char* str_after_last_replace; 271 272 search_len = avb_strlen(search); 273 replace_len = avb_strlen(replace); 274 275 str_after_last_replace = str; 276 while (*str != '\0') { 277 const char* s; 278 size_t num_before; 279 size_t num_new; 280 281 s = avb_strstr(str, search); 282 if (s == NULL) { 283 break; 284 } 285 286 num_before = s - str; 287 288 if (ret == NULL) { 289 num_new = num_before + replace_len + 1; 290 ret = avb_malloc(num_new); 291 if (ret == NULL) { 292 goto out; 293 } 294 avb_memcpy(ret, str, num_before); 295 avb_memcpy(ret + num_before, replace, replace_len); 296 ret[num_new - 1] = '\0'; 297 ret_len = num_new - 1; 298 } else { 299 char* new_str; 300 num_new = ret_len + num_before + replace_len + 1; 301 new_str = avb_malloc(num_new); 302 if (ret == NULL) { 303 goto out; 304 } 305 avb_memcpy(new_str, ret, ret_len); 306 avb_memcpy(new_str + ret_len, str, num_before); 307 avb_memcpy(new_str + ret_len + num_before, replace, replace_len); 308 new_str[num_new - 1] = '\0'; 309 avb_free(ret); 310 ret = new_str; 311 ret_len = num_new - 1; 312 } 313 314 str = s + search_len; 315 str_after_last_replace = str; 316 } 317 318 if (ret == NULL) { 319 ret = avb_strdup(str_after_last_replace); 320 if (ret == NULL) { 321 goto out; 322 } 323 } else { 324 size_t num_remaining = avb_strlen(str_after_last_replace); 325 size_t num_new = ret_len + num_remaining + 1; 326 char* new_str = avb_malloc(num_new); 327 if (ret == NULL) { 328 goto out; 329 } 330 avb_memcpy(new_str, ret, ret_len); 331 avb_memcpy(new_str + ret_len, str_after_last_replace, num_remaining); 332 new_str[num_new - 1] = '\0'; 333 avb_free(ret); 334 ret = new_str; 335 ret_len = num_new - 1; 336 } 337 338 out: 339 return ret; 340 } 341 342 /* We only support a limited amount of strings in avb_strdupv(). */ 343 #define AVB_STRDUPV_MAX_NUM_STRINGS 32 344 345 char* avb_strdupv(const char* str, ...) { 346 va_list ap; 347 const char* strings[AVB_STRDUPV_MAX_NUM_STRINGS]; 348 size_t lengths[AVB_STRDUPV_MAX_NUM_STRINGS]; 349 size_t num_strings, n; 350 uint64_t total_length; 351 char *ret = NULL, *dest; 352 353 num_strings = 0; 354 total_length = 0; 355 va_start(ap, str); 356 do { 357 size_t str_len = avb_strlen(str); 358 strings[num_strings] = str; 359 lengths[num_strings] = str_len; 360 if (!avb_safe_add_to(&total_length, str_len)) { 361 avb_fatal("Overflow while determining total length.\n"); 362 break; 363 } 364 num_strings++; 365 if (num_strings == AVB_STRDUPV_MAX_NUM_STRINGS) { 366 avb_fatal("Too many strings passed.\n"); 367 break; 368 } 369 str = va_arg(ap, const char*); 370 } while (str != NULL); 371 va_end(ap); 372 373 ret = avb_malloc(total_length + 1); 374 if (ret == NULL) { 375 goto out; 376 } 377 378 dest = ret; 379 for (n = 0; n < num_strings; n++) { 380 avb_memcpy(dest, strings[n], lengths[n]); 381 dest += lengths[n]; 382 } 383 *dest = '\0'; 384 avb_assert(dest == ret + total_length); 385 386 out: 387 return ret; 388 } 389 390 const char* avb_basename(const char* str) { 391 int64_t n; 392 size_t len; 393 394 len = avb_strlen(str); 395 if (len >= 2) { 396 for (n = len - 2; n >= 0; n--) { 397 if (str[n] == '/') { 398 return str + n + 1; 399 } 400 } 401 } 402 return str; 403 } 404