aheinecke@404: /* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik aheinecke@404: * Software engineering by Intevation GmbH aheinecke@404: * aheinecke@404: * This file is Free Software under the GNU GPL (v>=2) aheinecke@404: * and comes with ABSOLUTELY NO WARRANTY! aheinecke@404: * See LICENSE.txt for details. aheinecke@404: */ wilde@319: /* Needed to get asprintf */ wilde@319: #define _GNU_SOURCE 1 wilde@319: wilde@134: #include wilde@319: #include wilde@131: #include aheinecke@59: #include aheinecke@59: #include aheinecke@59: #include aheinecke@59: #include aheinecke@59: aheinecke@160: #include aheinecke@160: aheinecke@251: #ifdef WIN32 aheinecke@251: #include aheinecke@251: #endif aheinecke@251: wilde@143: /* Remarks regarding the "Flawfinder: ignore" comments in this file: wilde@143: * wilde@143: * - strlen: wilde@143: * wilde@143: * It's true that strlen might crash if input is not null wilde@143: * terminated. But by design there is not safe way to get the wilde@143: * length of an string in C, and defining an additional length wilde@143: * parameter for string parameter will only transfere the problem to wilde@143: * the caller. wilde@143: */ wilde@143: aheinecke@59: static void aheinecke@59: out_of_core(void) aheinecke@59: { andre@905: fputs("\nfatal: out of memory\n", stderr); andre@905: exit(2); aheinecke@59: } aheinecke@59: void * aheinecke@59: xmalloc( size_t n ) aheinecke@59: { andre@905: void *p = malloc( n ); andre@905: if( !p ) andre@905: out_of_core(); andre@905: return p; aheinecke@59: } aheinecke@59: aheinecke@59: void * aheinecke@59: xrealloc( void *a, size_t n ) aheinecke@59: { andre@905: void *p = realloc( a, n ); andre@905: if( !p ) andre@905: out_of_core(); andre@905: return p; aheinecke@59: } aheinecke@59: aheinecke@59: char * aheinecke@60: xstrndup( const char *string, const size_t len ) aheinecke@59: { andre@905: char *p = xmalloc( len + 1 ); andre@905: memcpy( p, string, len ); andre@905: p[len] = '\0'; andre@905: return p; aheinecke@59: } aheinecke@59: aheinecke@59: unsigned int aheinecke@59: strv_length (char **str_array) aheinecke@59: { andre@905: unsigned int i = 0; aheinecke@59: andre@905: if (!str_array) andre@905: return 0; aheinecke@59: andre@905: while (str_array[i]) andre@905: ++i; aheinecke@59: andre@905: return i; aheinecke@59: } aheinecke@59: wilde@116: void strv_append (char ***pArray, const char *string, const size_t len) aheinecke@59: { andre@905: unsigned int old_len = 0; aheinecke@60: andre@905: if (!*pArray) andre@905: { andre@905: *pArray = xmalloc(2 * sizeof(char*)); andre@905: (*pArray)[0] = xstrndup(string, len); andre@905: (*pArray)[1] = NULL; andre@905: return; aheinecke@60: } andre@905: old_len = strv_length(*pArray); andre@905: *pArray = xrealloc(*pArray, sizeof(char**) * (old_len + 2)); aheinecke@59: andre@905: (*pArray)[old_len] = xstrndup(string, len); andre@905: (*pArray)[old_len + 1] = NULL; aheinecke@59: } aheinecke@59: aheinecke@91: void aheinecke@91: str_append_str(char **pDst, size_t *dst_len, const char *appendage, const size_t len) aheinecke@59: { andre@905: if (!appendage) andre@905: return; aheinecke@59: andre@905: if (!(*pDst)) andre@905: { andre@905: *pDst = xstrndup(appendage, len); andre@905: *dst_len = len; andre@905: } andre@905: else andre@905: { andre@905: size_t new_size = (*dst_len) + len + 1; andre@905: char *p_old = *pDst; andre@905: *pDst = xmalloc(new_size); andre@905: strncpy(*pDst, p_old, *dst_len); andre@905: strncpy(*pDst + *dst_len, appendage, len); andre@905: *dst_len = new_size - 1; andre@905: (*pDst)[*dst_len] = '\0'; andre@905: free (p_old); aheinecke@60: } aheinecke@59: } aheinecke@59: aheinecke@59: void wilde@116: strv_free (char **str_array) aheinecke@59: { aheinecke@59: if (str_array) aheinecke@59: { aheinecke@59: int i; aheinecke@59: aheinecke@59: for (i = 0; str_array[i] != NULL; i++) aheinecke@59: free (str_array[i]); aheinecke@59: aheinecke@59: free (str_array); aheinecke@59: } aheinecke@59: } wilde@131: wilde@131: bool wilde@131: str_equal (char *s1, char *s2) wilde@131: { wilde@143: size_t l1 = strlen(s1); /* Flawfinder: ignore */ wilde@143: size_t l2 = strlen(s2); /* Flawfinder: ignore */ wilde@131: if ((l1 == l2) && wilde@136: (strcmp(s1, s2) == 0)) wilde@131: return true; wilde@131: else wilde@131: return false; wilde@131: } wilde@131: wilde@131: bool wilde@131: str_starts_with (char *s1, char *s2) wilde@131: { wilde@143: size_t l2 = strlen(s2); /* Flawfinder: ignore */ wilde@143: if (strncmp(s1, s2, l2) == 0) wilde@131: return true; wilde@131: else wilde@131: return false; wilde@131: } wilde@133: wilde@133: void wilde@133: str_trim (char **s) wilde@133: { wilde@133: size_t i; wilde@135: if (*s != NULL) wilde@135: { wilde@135: while (isspace(**s)) wilde@135: (*s)++; wilde@143: i = strlen(*s); /* Flawfinder: ignore */ wilde@135: while (isspace((*s)[--i])) wilde@135: (*s)[i] = '\0'; wilde@135: } wilde@133: } aheinecke@160: aheinecke@160: int str_base64_decode(char **dst, size_t *dst_size, char *src, aheinecke@160: size_t src_size) aheinecke@160: { andre@905: int ret = -1; aheinecke@160: andre@905: if (!dst || *dst) andre@905: { andre@905: return -1; aheinecke@160: } aheinecke@160: andre@905: /* Check the needed size for the buffer */ andre@905: ret = base64_decode(NULL, dst_size, andre@905: (unsigned char *)src, src_size); aheinecke@160: andre@905: if (ret != 0 && ret != POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL) andre@905: { andre@905: return ret; aheinecke@160: } aheinecke@160: andre@905: *dst = xmalloc(*dst_size); andre@905: memset (*dst, 0, *dst_size); aheinecke@160: andre@905: ret = base64_decode((unsigned char *)*dst, dst_size, andre@905: (unsigned char *)src, src_size); andre@905: if (ret) andre@905: { andre@905: free (*dst); andre@905: *dst = NULL; andre@905: *dst_size = 0; aheinecke@160: } andre@905: return ret; aheinecke@160: } aheinecke@251: aheinecke@251: void aheinecke@251: xfree (void *p) aheinecke@251: { aheinecke@251: if (p) aheinecke@251: free (p); aheinecke@251: } aheinecke@251: wilde@319: int wilde@319: xasprintf (char **strp, const char *fmt, ...) wilde@319: { wilde@319: int ret; wilde@319: va_list ap; wilde@319: va_start(ap, fmt); wilde@319: ret = vasprintf(strp, fmt, ap); wilde@319: va_end(ap); wilde@319: wilde@319: if (ret == -1) wilde@319: out_of_core(); wilde@319: wilde@319: return ret; wilde@319: } wilde@319: aheinecke@251: #ifdef WIN32 aheinecke@251: /* Adapted from GPGOL rev. e512053 */ aheinecke@251: char * aheinecke@251: wchar_to_utf8 (const wchar_t *string, size_t len) aheinecke@251: { aheinecke@251: int n, ilen; aheinecke@251: char *result; aheinecke@251: aheinecke@251: ilen = (int) len; aheinecke@251: if (ilen < 0) aheinecke@251: return NULL; aheinecke@251: aheinecke@251: /* Note, that CP_UTF8 is not defined in Windows versions earlier aheinecke@251: than NT.*/ aheinecke@251: n = WideCharToMultiByte (CP_UTF8, 0, string, ilen, NULL, 0, NULL, NULL); aheinecke@251: if (n < 0) aheinecke@251: return NULL; aheinecke@251: aheinecke@251: result = xmalloc ((size_t)n+1); aheinecke@251: n = WideCharToMultiByte (CP_UTF8, 0, string, ilen, result, n, NULL, NULL); aheinecke@251: if (n < 0) aheinecke@251: { aheinecke@251: xfree (result); aheinecke@251: return NULL; aheinecke@251: } aheinecke@288: result[n] = 0; aheinecke@251: return result; aheinecke@251: } aheinecke@251: aheinecke@251: /* Adapted from GPGOL rev. e512053 */ aheinecke@251: wchar_t * aheinecke@251: utf8_to_wchar (const char *string, size_t len) aheinecke@251: { aheinecke@251: int n, ilen; aheinecke@251: wchar_t *result; aheinecke@251: aheinecke@251: ilen = (int) len; aheinecke@251: if (ilen < 0) aheinecke@251: return NULL; aheinecke@251: aheinecke@251: n = MultiByteToWideChar (CP_UTF8, 0, string, ilen, NULL, 0); aheinecke@251: if (n < 0 || n + 1 < 0) aheinecke@251: return NULL; aheinecke@251: aheinecke@251: result = xmalloc ((size_t)(n+1) * sizeof *result); aheinecke@251: n = MultiByteToWideChar (CP_UTF8, 0, string, ilen, result, n); aheinecke@251: if (n < 0) aheinecke@251: { aheinecke@251: xfree (result); aheinecke@251: return NULL; aheinecke@251: } aheinecke@251: result[n] = 0; aheinecke@251: return result; aheinecke@251: } andre@1158: andre@1158: wchar_t andre@1158: *acp_to_wchar (const char *string, size_t len) andre@1158: { andre@1158: int n, ilen; andre@1158: wchar_t *result; andre@1158: andre@1158: ilen = (int) len; andre@1158: if (ilen < 0) andre@1158: return NULL; andre@1158: andre@1158: n = MultiByteToWideChar (CP_ACP, 0, string, ilen, NULL, 0); andre@1158: if (n < 0 || n + 1 < 0) andre@1158: return NULL; andre@1158: andre@1158: result = xmalloc ((size_t)(n+1) * sizeof *result); andre@1158: n = MultiByteToWideChar (CP_ACP, 0, string, ilen, result, n); andre@1158: if (n < 0) andre@1158: { andre@1158: xfree (result); andre@1158: return NULL; andre@1158: } andre@1158: result[n] = 0; andre@1158: return result; andre@1158: } aheinecke@251: #endif