chiark / gitweb /
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 cc319ce0be40046e92f6056dbb350b2a18d43815..88b76669cb9395858714afdc002d6e66669c242a 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;