Subversion Repositories

?revision_form?Rev ?revision_input??revision_submit??revision_endform?

Rev 23 | Blame | Compare with Previous | Last modification | View Log | RSS feed

From: Kamil Dudka <kdudka@redhat.com>
Date: Wed, 23 Oct 2013 13:04:22 +0000 (+0200)
Origin: http://repo.or.cz/w/libtar.git/commitdiff/ec613af2e9371d7a3e1f7c7a6822164a4255b4d1
Subject: decode: avoid using a static buffer in th_get_pathname()

decode: avoid using a static buffer in th_get_pathname()

A solution suggested by Chris Frey:
https://lists.feep.net:8080/pipermail/libtar/2013-October/000377.html

Note this can break programs that expect sizeof(TAR) to be fixed.

--- a/lib/decode.c
+++ b/lib/decode.c
@@ -13,6 +13,7 @@
 #include <internal.h>
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <sys/param.h>
 #include <pwd.h>
 #include <grp.h>
@@ -26,20 +27,30 @@
 char *
 th_get_pathname(TAR *t)
 {
-       static TLS_THREAD char filename[MAXPATHLEN];
-
        if (t->th_buf.gnu_longname)
                return t->th_buf.gnu_longname;
 
-       if (t->th_buf.prefix[0] != '\0')
+       /* allocate the th_pathname buffer if not already */
+       if (t->th_pathname == NULL)
+       {
+               t->th_pathname = malloc(MAXPATHLEN * sizeof(char));
+               if (t->th_pathname == NULL)
+                       /* out of memory */
+                       return NULL;
+       }
+
+       if (t->th_buf.prefix[0] == '\0')
+       {
+               snprintf(t->th_pathname, MAXPATHLEN, "%.100s", t->th_buf.name);
+       }
+       else
        {
-               snprintf(filename, sizeof(filename), "%.155s/%.100s",
+               snprintf(t->th_pathname, MAXPATHLEN, "%.155s/%.100s",
                         t->th_buf.prefix, t->th_buf.name);
-               return filename;
        }
 
-       snprintf(filename, sizeof(filename), "%.100s", t->th_buf.name);
-       return filename;
+       /* will be deallocated in tar_close() */
+       return t->th_pathname;
 }
 
 
--- a/lib/handle.c
+++ b/lib/handle.c
@@ -121,6 +121,7 @@ tar_close(TAR *t)
                libtar_hash_free(t->h, ((t->oflags & O_ACCMODE) == O_RDONLY
                                        ? free
                                        : (libtar_freefunc_t)tar_dev_free));
+       free(t->th_pathname);
        free(t);
 
        return i;
--- a/lib/libtar.h
+++ b/lib/libtar.h
@@ -85,6 +85,9 @@ typedef struct
        int options;
        struct tar_header th_buf;
        libtar_hash_t *h;
+
+       /* introduced in libtar 1.2.21 */
+       char *th_pathname;
 }
 TAR;