about summary refs log tree commit diff
path: root/src/afl-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/afl-common.c')
-rw-r--r--src/afl-common.c98
1 files changed, 96 insertions, 2 deletions
diff --git a/src/afl-common.c b/src/afl-common.c
index 06c691b3..f175f604 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -50,11 +50,86 @@ void detect_file_args(char** argv, u8* prog_in, u8 use_stdin) {
   if ((buf = (char*)malloc((size_t)size)) != NULL) {
 
     cwd = getcwd(buf, (size_t)size);                    /* portable version */
+    ck_free(buf);
 
   } else {
 
+    cwd = 0;                                          /* for dumb compilers */
     PFATAL("getcwd() failed");
+
+  }
+#endif
+
+  if (!cwd) PFATAL("getcwd() failed");
+
+  // TODO: free allocs below... somewhere.
+
+  while (argv[i]) {
+
+    u8* aa_loc = strstr(argv[i], "@@");
+
+    if (aa_loc) {
+
+      u8 *aa_subst, *n_arg;
+
+      if (!prog_in) FATAL("@@ syntax is not supported by this tool.");
+
+      use_stdin = 0;
+
+      if (prog_in[0] != 0) {  // not afl-showmap special case
+
+        /* Be sure that we're always using fully-qualified paths. */
+
+        if (prog_in[0] == '/')
+          aa_subst = prog_in;
+        else
+          aa_subst = alloc_printf("%s/%s", cwd, prog_in);
+
+        /* Construct a replacement argv value. */
+
+        // TODO: n_arg is never freed
+
+        *aa_loc = 0;
+        n_arg = alloc_printf("%s%s%s", argv[i], aa_subst, aa_loc + 2);
+        argv[i] = n_arg;
+        *aa_loc = '@';
+
+        if (prog_in[0] != '/') ck_free(aa_subst);
+
+      }
+
+    }
+
+    i++;
+
+  }
+
+  ck_free(cwd);                                                 /* not tracked */
+
+}
+
+
+char **create_file_args(int argc, char** argv, u8* prog_in, u8 use_stdin) {
+
+  u32 i = 0;
+
+  char **ret = malloc((argc + 1) * sizeof(char));
+
+#ifdef __GLIBC__
+  u8* cwd = getcwd(NULL, 0);                /* non portable glibc extension */
+#else
+  u8*   cwd;
+  char* buf;
+  long  size = pathconf(".", _PC_PATH_MAX);
+  if ((buf = (char*)malloc((size_t)size)) != NULL) {
+
+    cwd = getcwd(buf, (size_t)size);                    /* portable version */
+    ck_free(buf);
+
+  } else {
+
     cwd = 0;                                          /* for dumb compilers */
+    PFATAL("getcwd() failed");
 
   }
 
@@ -91,23 +166,42 @@ void detect_file_args(char** argv, u8* prog_in, u8 use_stdin) {
 
         *aa_loc = 0;
         n_arg = alloc_printf("%s%s%s", argv[i], aa_subst, aa_loc + 2);
-        argv[i] = n_arg;
+        ret[i] = n_arg;
         *aa_loc = '@';
 
         if (prog_in[0] != '/') ck_free(aa_subst);
 
+        i++;
+        continue;
+
       }
 
     }
 
+    ret[i] = ck_strdup(argv[i]);
     i++;
 
   }
+  ret[i] = NULL;
 
-  free(cwd);                                                 /* not tracked */
+  ck_free(cwd);                                                 /* not tracked */
 
+  return ret;
 }
 
+/* frees all args in the given argv, 
+   previously created by create_file_args */
+void destroy_file_args(char **argv) {
+
+  u32 i=0;
+  while(argv[i]) {
+    ck_free(argv[i]);
+    i++;
+  }
+  ck_free(argv);
+}
+
+
 /* Rewrite argv for QEMU. */
 
 char** get_qemu_argv(u8* own_loc, u8** target_path_p, int argc, char** argv) {