changeset 60:6acb1dae6185

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.
author Andre Heinecke <aheinecke@intevation.de>
date Tue, 18 Mar 2014 11:28:02 +0000
parents 3f6378647371
children b8cd573bd3ac
files cinst/main.c common/errorcodes.h common/strhelp.c common/strhelp.h
diffstat 4 files changed, 65 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
--- 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));
 
--- /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
--- 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
--- 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

http://wald.intevation.org/projects/trustbridge/