# HG changeset patch # User Andre Heinecke # Date 1395142082 0 # Node ID 6acb1dae6185956469d8ee16c16c0fbb636685f1 # Parent 3f63786473716a03aca4ef51705d0761eb92f70b Use strn functions and improve error handling. Even if we know the strings are NULL terminated we use length terminated string functions after a first strlen this makes it easier to assert that at one point we know the string is terminated and afterwards use the length of that. diff -r 3f6378647371 -r 6acb1dae6185 cinst/main.c --- a/cinst/main.c Tue Mar 18 10:04:30 2014 +0000 +++ b/cinst/main.c Tue Mar 18 11:28:02 2014 +0000 @@ -34,6 +34,7 @@ #include "strhelp.h" #include "listutil.h" +#include "errorcodes.h" /* @brief Read stdin into data structures. * @@ -41,9 +42,12 @@ * variables. The pointers returned need to be freed by the caller. * Terminates in OOM conditions. * - * @returns: 0 on success. -1 otherwise. + * The caller needs to free the memory allocated by this function + * even when an error is returned. + * + * @returns: 0 on success. An error code otherwise. */ -void readInput(char **certificateList, char ***to_install, +int readInput(char **certificateList, char ***to_install, char ***to_remove) { int lines_read = 0; @@ -51,8 +55,10 @@ char buf[MAX_LINE_LENGTH + 1]; while (fgets(buf, MAX_LINE_LENGTH + 1, stdin)) { + size_t len = strlen(buf); /* fgets ensures buf is terminated */ if (lines_read ++ > MAX_LINES) { printf("Too many lines\n"); + return ERR_TOO_MUCH_INPUT; } if (strcmp("-----BEGIN CERTIFICATE LIST-----", buf) == 0){ readingList = 1; @@ -63,23 +69,23 @@ continue; } if (readingList) { - str_append_str(certificateList, buf); + str_append_str(certificateList, buf, len); continue; } if (*buf == 'I') { - array_append_str(to_install, buf+2); + array_append_str(to_install, buf+2, len - 2); continue; } if (*buf == 'R') { - array_append_str(to_remove, buf+2); + array_append_str(to_remove, buf+2, len - 2); continue; } if (strcmp("UNINSTALL", buf) == 0) { - array_append_str(to_remove, buf); + array_append_str(to_remove, buf, len - 2); } } - return; + return 0; } int main() { @@ -89,7 +95,15 @@ char *certificateList = NULL; int ret = -1; - readInput(&certificateList, &to_install, &to_remove); + ret = readInput(&certificateList, &to_install, &to_remove); + + if (ret != 0) { + return ret; + } + + if (!certificateList) { + return ERR_INVALID_INPUT_NO_LIST; + } ret = verify_list(certificateList, strlen(certificateList)); diff -r 3f6378647371 -r 6acb1dae6185 common/errorcodes.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/errorcodes.h Tue Mar 18 11:28:02 2014 +0000 @@ -0,0 +1,9 @@ +#ifndef ERRORCODES_H +#define ERRORCODES_H + +/* No begin certificate / end certificate could be found */ +#define ERR_INVALID_INPUT_NO_LIST 2 +/* Too much input for the installer process */ +#define ERR_TOO_MUCH_INPUT 3 + +#endif diff -r 3f6378647371 -r 6acb1dae6185 common/strhelp.c --- a/common/strhelp.c Tue Mar 18 10:04:30 2014 +0000 +++ b/common/strhelp.c Tue Mar 18 11:28:02 2014 +0000 @@ -29,24 +29,14 @@ } char * -xstrdup( const char *string ) +xstrndup( const char *string, const size_t len ) { - void *p = xmalloc( strlen(string)+1 ); - strcpy( p, string ); + char *p = xmalloc( len + 1 ); + memcpy( p, string, len ); + p[len] = '\0'; return p; } - -/** - * strv_length: - * @str_array: a %NULL-terminated array of strings - * - * Returns the length of the given %NULL-terminated - * string array @str_array. - * - * Return value: length of @str_array. - * - */ unsigned int strv_length (char **str_array) { @@ -61,39 +51,37 @@ return i; } -/* @brief append a string to a NULL terminated array of strings. - * - * @param[inout] array pointer to the NULL terminated list of string pointers. - * @param[in] string pointer to the string to append to the list. - * */ -void array_append_str(char ***pArray, const char *string) +void array_append_str(char ***pArray, const char *string, const size_t len) { - unsigned int old_len = strv_length(*pArray); + unsigned int old_len = 0; + + if (!*pArray) { + *pArray = xmalloc(2 * sizeof(char*)); + (*pArray)[0] = xstrndup(string, len); + (*pArray)[1] = NULL; + return; + } + old_len = strv_length(*pArray); *pArray = xrealloc(*pArray, sizeof(char**) * (old_len + 2)); - *pArray[old_len] = xstrdup(string); - *pArray[old_len + 1] = NULL; + (*pArray)[old_len] = xstrndup(string, len); + (*pArray)[old_len + 1] = NULL; } -/* @brief append a string to another string. - * - * @param[inout] pDst pointer to the string to be extended. - * @param[in] appendage pointer to the string to append. - * */ -void str_append_str(char **pDst, const char *appendage) +void str_append_str(char **pDst, const char *appendage, const size_t len) { - size_t old_len = strlen(*pDst), - added_len = strlen(appendage); - size_t new_len = old_len + added_len + 1; - if (!appendage) return; - *pDst = (char *)xrealloc(*pDst, sizeof(char) * (new_len)); - - strcpy(*pDst + old_len, appendage); - - *pDst[new_len - 1] = '\0'; + if (!*pDst) { + *pDst = xstrndup(appendage, len); + } else { + size_t old_len = strlen(*pDst); + size_t new_len = old_len + len + 1; + *pDst = (char *)xrealloc(*pDst, sizeof(char) * (new_len)); + strncpy(*pDst + old_len, appendage, new_len); + *pDst[new_len] = '\0'; + } } void diff -r 3f6378647371 -r 6acb1dae6185 common/strhelp.h --- a/common/strhelp.h Tue Mar 18 10:04:30 2014 +0000 +++ b/common/strhelp.h Tue Mar 18 11:28:02 2014 +0000 @@ -1,3 +1,5 @@ +#ifndef STRHELP_H +#define STRHELP_H /* @file Helper functions for c strings and memory management * * strhelp contains terminating memory allocation functions and @@ -7,7 +9,7 @@ void *xmalloc( size_t n ); void *xrealloc( void *a, size_t n ); void *xcalloc( size_t n, size_t m ); -char *xstrdup( const char *string ); +char *xstrndup( const char *string, const size_t len ); /** * strv_length: @@ -25,14 +27,17 @@ * * @param[inout] array pointer to the NULL terminated list of string pointers. * @param[in] string pointer to the string to append to the list. + * @param[in] len length of the string to append to the list * */ -void array_append_str(char ***pArray, const char *string); +void array_append_str(char ***pArray, const char *string, const size_t len); /* @brief append a string to another string. * * @param[inout] pDst pointer to the string to be extended. * @param[in] appendage pointer to the string to append. + * @param[in] len length of the string to append. * */ -void str_append_str(char **pDst, const char *appendage); +void str_append_str(char **pDst, const char *appendage, const size_t len); void strfreev (char **str_array); +#endif