file.c (file_read): Copy name when duplicating input file spec.
authorMark Wooding <mdw@distorted.org.uk>
Fri, 13 May 2011 19:26:13 +0000 (20:26 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Fri, 13 May 2011 19:26:13 +0000 (20:26 +0100)
If only one filespec is provided to the file endpoint, then it copies
the input spec (which it's already parsed) to the output.  But this
isn't enough because the spec might contain a dynamically allocated
filename.  The function `file_destroy' unconditionally frees both names,
which is a double-free bug.

Fix this in the stupid way, by allocating a separate copy of the
filename if we duplicate the input filespec.  (I could fix it in
`file_destroy' instead, but that becomes a little fiddly, and it's
rather brittle.

file.c

diff --git a/file.c b/file.c
index cc319ce..88b7666 100644 (file)
--- a/file.c
+++ b/file.c
@@ -242,13 +242,15 @@ static void file_fspec(fspec *f, scanner *sc)
 static void file_read(fdata *f, scanner *sc)
 {
   file_fspec(&f->in, sc);
-  if (sc->t != ',') {
+  if (sc->t == ',') {
+    token(sc);
+    file_fspec(&f->out, sc);
+  } else {
     f->out = f->in;
     if (f->out.type == FTYPE_FD && f->out.u.fd == rstdin)
       f->out.u.fd = rstdout;
-  } else {
-    token(sc);
-    file_fspec(&f->out, sc);
+    else if (f->out.type == FTYPE_NAME)
+      f->out.u.name = xstrdup(f->in.u.name);
   }
   f->fa = fattr_global;
   f->fo = file_opts;