diff cinst/main.c @ 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 fb9f78f7ab2f
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));
 

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