fuse_session_new(): don't accept empty argv, check argv[0]
authorNikolaus Rath <Nikolaus@rath.org>
Tue, 25 Oct 2016 03:31:29 +0000 (20:31 -0700)
committerNikolaus Rath <Nikolaus@rath.org>
Tue, 25 Oct 2016 03:31:29 +0000 (20:31 -0700)
This should help avoid people to accidentally put options
into argv[0].

Fixes #100.

ChangeLog.rst
include/fuse.h
include/fuse_lowlevel.h
lib/fuse_lowlevel.c

index e614e6b40c360d45c99837efce40f1fab5e8c55c..2019325a0120689a04b3542f70af42c5aea46a3e 100644 (file)
@@ -1,6 +1,10 @@
 Unreleased Changes
 ==================
 
+* Documentation: clarified that the fuse_argv structure that is passed
+  to `fuse_new()` and `fuse_lowlevel_new()` must always contain at
+  least one element.
+
 * The high-level init() handler now receives an additional struct
   fuse_config pointer that can be used to adjust high-level API
   specific configuration options.
index e8ff9361ec61bcba03003b553405ecc58747e2e2..312818e8430a98ae09838a19aff81c241ec50a47 100644 (file)
@@ -748,11 +748,13 @@ struct fuse_context {
  * fuse_main() accepts all options that can be passed to
  * fuse_parse_cmdline(), fuse_new(), or fuse_session_new().
  *
- * Normally, fuse_main() includes a basic ``usage: `` message in the
- * --help output. However, if argv[0] is an empty string, the usage
- * message is suppressed. This can be used by file systems to print
- * their own usage line first. See hello.c for an example of how to do
- * this.
+ * Option parsing skips argv[0], which is assumed to contain the
+ * program name. This element must always be present and is used to
+ * construct a basic ``usage: `` message for the --help
+ * output. argv[0] may also be set to the empty string. In this case
+ * the usage message is suppressed. This can be used by file systems
+ * to print their own usage line first. See hello.c for an example of
+ * how to do this.
  *
  * Note: this is currently implemented as a macro.
  *
@@ -785,6 +787,12 @@ struct fuse_context {
  * If the --help option is specified, the function writes a help text
  * to stdout and returns NULL.
  *
+ * Option parsing skips argv[0], which is assumed to contain the
+ * program name. This element must always be present and is used to
+ * construct a basic ``usage: `` message for the --help output. If
+ * argv[0] is set to the empty string, no usage message is included in
+ * the --help output.
+ *
  * If an unknown option is passed in, an error message is written to
  * stderr and the function returns NULL.
  *
index 8ec95b5bea16f95ded72943c17bfd44de11d2f10..e6f95a99ea6262eb3b7d95e095621f598980c521 100644 (file)
@@ -1655,6 +1655,12 @@ int fuse_parse_cmdline(struct fuse_args *args,
  * If not all options are known, an error message is written to stderr
  * and the function returns NULL.
  *
+ * Option parsing skips argv[0], which is assumed to contain the
+ * program name. To prevent accidentially passing an option in
+ * argv[0], this element must always be present (even if no options
+ * are specified). It may be set to the empty string ('\0') if no
+ * reasonable value can be provided.
+ *
  * @param args argument vector
  * @param op the (low-level) filesystem operations
  * @param op_size sizeof(struct fuse_lowlevel_ops)
index 8889d2d6f20ac9d0ef50227111e3980e1e404bf7..3aa12dedaaaa6d550a6ff4440bfdad4191fd8568 100644 (file)
@@ -2739,6 +2739,11 @@ struct fuse_session *fuse_session_new(struct fuse_args *args,
                op_size = sizeof(struct fuse_lowlevel_ops);
        }
 
+       if (args->argc == 0) {
+               fprintf(stderr, "fuse: empty argv passed to fuse_session_new().\n");
+               return NULL;
+       }
+
        se = (struct fuse_session *) calloc(1, sizeof(struct fuse_session));
        if (se == NULL) {
                fprintf(stderr, "fuse: failed to allocate fuse object\n");
@@ -2754,7 +2759,12 @@ struct fuse_session *fuse_session_new(struct fuse_args *args,
                goto out2;
        if(fuse_opt_parse(args, se, fuse_ll_opts, NULL) == -1)
                goto out3;
-       if (args->argc != 1) {
+
+       if(args->argc == 1 &&
+          args->argv[0][0] == '-') {
+               fprintf(stderr, "fuse: warning: argv[0] looks like an option, but "
+                       "will be ignored\n");
+       } else if (args->argc != 1) {
                int i;
                fprintf(stderr, "fuse: unknown option(s): `");
                for(i = 1; i < args->argc-1; i++)