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