summaryrefslogtreecommitdiffstats
path: root/Utilities/cmtar
diff options
context:
space:
mode:
authorDavid Cole <david.cole@kitware.com>2006-02-03 16:48:44 (GMT)
committerDavid Cole <david.cole@kitware.com>2006-02-03 16:48:44 (GMT)
commit0323a0d6d20402d994f4f886d51b8c33c02ed73a (patch)
tree9ac42eed35f442353e0068fbe898120444f853a5 /Utilities/cmtar
parentafa83678854b7af547c9f0033ac5f7446a163447 (diff)
downloadCMake-0323a0d6d20402d994f4f886d51b8c33c02ed73a.zip
CMake-0323a0d6d20402d994f4f886d51b8c33c02ed73a.tar.gz
CMake-0323a0d6d20402d994f4f886d51b8c33c02ed73a.tar.bz2
BUG: Fix mem leaks related to th_get_pathname. Change this implementation of th_get_pathname so that it *always* returns a strdup'ed value. Callers must now free non-NULL returns from th_get_pathname. Change all callers to call free appropriately.
Diffstat (limited to 'Utilities/cmtar')
-rw-r--r--Utilities/cmtar/decode.c4
-rw-r--r--Utilities/cmtar/extract.c249
-rw-r--r--Utilities/cmtar/output.c10
-rw-r--r--Utilities/cmtar/wrapper.c41
4 files changed, 286 insertions, 18 deletions
diff --git a/Utilities/cmtar/decode.c b/Utilities/cmtar/decode.c
index 788fb3f..d6a48c5 100644
--- a/Utilities/cmtar/decode.c
+++ b/Utilities/cmtar/decode.c
@@ -31,13 +31,15 @@
/* determine full path name */
+/* caller must "free" returned pointer when done with it */
+/* th_get_pathname return values come directly from strdup */
char *
th_get_pathname(TAR *t)
{
char filename[TAR_MAXPATHLEN];
if (t->th_buf.gnu_longname)
- return t->th_buf.gnu_longname;
+ return strdup(t->th_buf.gnu_longname);
if (t->th_buf.prefix[0] != '\0')
{
diff --git a/Utilities/cmtar/extract.c b/Utilities/cmtar/extract.c
index 52afbed..f1a6407 100644
--- a/Utilities/cmtar/extract.c
+++ b/Utilities/cmtar/extract.c
@@ -61,8 +61,18 @@ tar_set_file_perms(TAR *t, char *realname)
gid_t gid;
struct utimbuf ut;
char *filename;
+ char *pathname = 0;
+
+ if (realname)
+ {
+ filename = realname;
+ }
+ else
+ {
+ pathname = th_get_pathname(t);
+ filename = pathname;
+ }
- filename = (realname ? realname : th_get_pathname(t));
mode = th_get_mode(t);
uid = th_get_uid(t);
gid = th_get_gid(t);
@@ -86,6 +96,10 @@ tar_set_file_perms(TAR *t, char *realname)
filename, uid, gid, strerror(errno));
# endif
#endif /* HAVE_LCHOWN */
+ if (pathname)
+ {
+ free(pathname);
+ }
return -1;
}
@@ -95,6 +109,10 @@ tar_set_file_perms(TAR *t, char *realname)
#ifdef DEBUG
perror("utime()");
#endif
+ if (pathname)
+ {
+ free(pathname);
+ }
return -1;
}
/* change permissions */
@@ -103,6 +121,10 @@ tar_set_file_perms(TAR *t, char *realname)
#ifdef DEBUG
perror("chmod()");
#endif
+ if (pathname)
+ {
+ free(pathname);
+ }
return -1;
}
@@ -113,6 +135,10 @@ tar_set_file_perms(TAR *t, char *realname)
(void)mode;
#endif /* WIN32 */
+ if (pathname)
+ {
+ free(pathname);
+ }
return 0;
}
@@ -123,6 +149,7 @@ tar_extract_file(TAR *t, char *realname)
{
int i;
linkname_t *lnp;
+ char *pathname = 0;
if (t->options & TAR_NOOVERWRITE)
{
@@ -170,12 +197,17 @@ tar_extract_file(TAR *t, char *realname)
lnp = (linkname_t *)calloc(1, sizeof(linkname_t));
if (lnp == NULL)
return -1;
- strlcpy(lnp->ln_save, th_get_pathname(t), sizeof(lnp->ln_save));
+ pathname = th_get_pathname(t);
+ strlcpy(lnp->ln_save, pathname, sizeof(lnp->ln_save));
strlcpy(lnp->ln_real, realname, sizeof(lnp->ln_real));
#ifdef DEBUG
printf("tar_extract_file(): calling libtar_hash_add(): key=\"%s\", "
- "value=\"%s\"\n", th_get_pathname(t), realname);
+ "value=\"%s\"\n", pathname, realname);
#endif
+ if (pathname)
+ {
+ free(pathname);
+ }
if (libtar_hash_add(t->h, lnp) != 0)
return -1;
@@ -195,6 +227,7 @@ tar_extract_regfile(TAR *t, char *realname)
int i, k;
char buf[T_BLOCKSIZE];
char *filename;
+ char *pathname = 0;
#ifdef DEBUG
printf("==> tar_extract_regfile(t=0x%lx, realname=\"%s\")\n", t,
@@ -207,7 +240,15 @@ tar_extract_regfile(TAR *t, char *realname)
return -1;
}
- filename = (realname ? realname : th_get_pathname(t));
+ if (realname)
+ {
+ filename = realname;
+ }
+ else
+ {
+ pathname = th_get_pathname(t);
+ filename = pathname;
+ }
mode = th_get_mode(t);
size = th_get_size(t);
uid = th_get_uid(t);
@@ -220,6 +261,10 @@ tar_extract_regfile(TAR *t, char *realname)
if (mkdirhier(dirname(buf)) == -1)
{
+ if (pathname)
+ {
+ free(pathname);
+ }
return -1;
}
@@ -237,6 +282,10 @@ tar_extract_regfile(TAR *t, char *realname)
#ifdef DEBUG
perror("open()");
#endif
+ if (pathname)
+ {
+ free(pathname);
+ }
return -1;
}
@@ -247,6 +296,10 @@ tar_extract_regfile(TAR *t, char *realname)
#ifdef DEBUG
perror("fchown()");
#endif
+ if (pathname)
+ {
+ free(pathname);
+ }
return -1;
}
@@ -256,6 +309,10 @@ tar_extract_regfile(TAR *t, char *realname)
#ifdef DEBUG
perror("fchmod()");
#endif
+ if (pathname)
+ {
+ free(pathname);
+ }
return -1;
}
#endif
@@ -268,18 +325,34 @@ tar_extract_regfile(TAR *t, char *realname)
{
if (k != -1)
errno = EINVAL;
+ if (pathname)
+ {
+ free(pathname);
+ }
return -1;
}
/* write block to output file */
if (write(fdout, buf,
((i > T_BLOCKSIZE) ? T_BLOCKSIZE : i)) == -1)
+ {
+ if (pathname)
+ {
+ free(pathname);
+ }
return -1;
+ }
}
/* close output file */
if (close(fdout) == -1)
+ {
+ if (pathname)
+ {
+ free(pathname);
+ }
return -1;
+ }
#ifdef DEBUG
printf("### done extracting %s\n", filename);
@@ -290,6 +363,10 @@ tar_extract_regfile(TAR *t, char *realname)
(void)uid;
(void)mode;
+ if (pathname)
+ {
+ free(pathname);
+ }
return 0;
}
@@ -333,6 +410,7 @@ tar_extract_hardlink(TAR * t, char *realname)
linkname_t *lnp;
libtar_hashptr_t hp;
char buf[T_BLOCKSIZE];
+ char *pathname = 0;
if (!TH_ISLNK(t))
{
@@ -340,7 +418,15 @@ tar_extract_hardlink(TAR * t, char *realname)
return -1;
}
- filename = (realname ? realname : th_get_pathname(t));
+ if (realname)
+ {
+ filename = realname;
+ }
+ else
+ {
+ pathname = th_get_pathname(t);
+ filename = pathname;
+ }
/* Make a copy of the string because dirname and mkdirhier may modify the
* string */
@@ -348,7 +434,13 @@ tar_extract_hardlink(TAR * t, char *realname)
buf[sizeof(buf)-1] = 0;
if (mkdirhier(dirname(buf)) == -1)
+ {
+ if (pathname)
+ {
+ free(pathname);
+ }
return -1;
+ }
libtar_hashptr_reset(&hp);
if (libtar_hash_getkey(t->h, &hp, th_get_linkname(t),
(libtar_matchfunc_t)libtar_str_match) != 0)
@@ -371,9 +463,17 @@ tar_extract_hardlink(TAR * t, char *realname)
#ifdef DEBUG
perror("link()");
#endif
+ if (pathname)
+ {
+ free(pathname);
+ }
return -1;
}
+ if (pathname)
+ {
+ free(pathname);
+ }
return 0;
}
@@ -384,6 +484,7 @@ tar_extract_symlink(TAR *t, char *realname)
{
char *filename;
char buf[T_BLOCKSIZE];
+ char *pathname = 0;
#ifndef _WIN32
if (!TH_ISSYM(t))
@@ -393,7 +494,15 @@ tar_extract_symlink(TAR *t, char *realname)
}
#endif
- filename = (realname ? realname : th_get_pathname(t));
+ if (realname)
+ {
+ filename = realname;
+ }
+ else
+ {
+ pathname = th_get_pathname(t);
+ filename = pathname;
+ }
/* Make a copy of the string because dirname and mkdirhier may modify the
* string */
@@ -401,10 +510,20 @@ tar_extract_symlink(TAR *t, char *realname)
buf[sizeof(buf)-1] = 0;
if (mkdirhier(dirname(buf)) == -1)
+ {
+ if (pathname)
+ {
+ free(pathname);
+ }
return -1;
+ }
if (unlink(filename) == -1 && errno != ENOENT)
{
+ if (pathname)
+ {
+ free(pathname);
+ }
return -1;
}
@@ -419,9 +538,17 @@ tar_extract_symlink(TAR *t, char *realname)
#ifdef DEBUG
perror("symlink()");
#endif
+ if (pathname)
+ {
+ free(pathname);
+ }
return -1;
}
+ if (pathname)
+ {
+ free(pathname);
+ }
return 0;
}
@@ -434,6 +561,7 @@ tar_extract_chardev(TAR *t, char *realname)
unsigned long devmaj, devmin;
char *filename;
char buf[T_BLOCKSIZE];
+ char *pathname = 0;
#ifndef _WIN32
if (!TH_ISCHR(t))
@@ -442,7 +570,15 @@ tar_extract_chardev(TAR *t, char *realname)
return -1;
}
#endif
- filename = (realname ? realname : th_get_pathname(t));
+ if (realname)
+ {
+ filename = realname;
+ }
+ else
+ {
+ pathname = th_get_pathname(t);
+ filename = pathname;
+ }
mode = th_get_mode(t);
devmaj = th_get_devmajor(t);
devmin = th_get_devminor(t);
@@ -453,7 +589,13 @@ tar_extract_chardev(TAR *t, char *realname)
buf[sizeof(buf)-1] = 0;
if (mkdirhier(dirname(buf)) == -1)
+ {
+ if (pathname)
+ {
+ free(pathname);
+ }
return -1;
+ }
#ifdef DEBUG
printf(" ==> extracting: %s (character device %ld,%ld)\n",
@@ -471,9 +613,17 @@ tar_extract_chardev(TAR *t, char *realname)
#ifdef DEBUG
perror("mknod()");
#endif
+ if (pathname)
+ {
+ free(pathname);
+ }
return -1;
}
+ if (pathname)
+ {
+ free(pathname);
+ }
return 0;
}
@@ -486,6 +636,7 @@ tar_extract_blockdev(TAR *t, char *realname)
unsigned long devmaj, devmin;
char *filename;
char buf[T_BLOCKSIZE];
+ char *pathname = 0;
if (!TH_ISBLK(t))
{
@@ -493,7 +644,15 @@ tar_extract_blockdev(TAR *t, char *realname)
return -1;
}
- filename = (realname ? realname : th_get_pathname(t));
+ if (realname)
+ {
+ filename = realname;
+ }
+ else
+ {
+ pathname = th_get_pathname(t);
+ filename = pathname;
+ }
mode = th_get_mode(t);
devmaj = th_get_devmajor(t);
devmin = th_get_devminor(t);
@@ -504,7 +663,13 @@ tar_extract_blockdev(TAR *t, char *realname)
buf[sizeof(buf)-1] = 0;
if (mkdirhier(dirname(buf)) == -1)
+ {
+ if (pathname)
+ {
+ free(pathname);
+ }
return -1;
+ }
#ifdef DEBUG
printf(" ==> extracting: %s (block device %ld,%ld)\n",
@@ -522,9 +687,17 @@ tar_extract_blockdev(TAR *t, char *realname)
#ifdef DEBUG
perror("mknod()");
#endif
+ if (pathname)
+ {
+ free(pathname);
+ }
return -1;
}
+ if (pathname)
+ {
+ free(pathname);
+ }
return 0;
}
@@ -536,6 +709,7 @@ tar_extract_dir(TAR *t, char *realname)
mode_t mode;
char *filename;
char buf[T_BLOCKSIZE];
+ char *pathname = 0;
if (!TH_ISDIR(t))
{
@@ -543,7 +717,15 @@ tar_extract_dir(TAR *t, char *realname)
return -1;
}
- filename = (realname ? realname : th_get_pathname(t));
+ if (realname)
+ {
+ filename = realname;
+ }
+ else
+ {
+ pathname = th_get_pathname(t);
+ filename = pathname;
+ }
mode = th_get_mode(t);
/* Make a copy of the string because dirname and mkdirhier may modify the
@@ -552,7 +734,13 @@ tar_extract_dir(TAR *t, char *realname)
buf[sizeof(buf)-1] = 0;
if (mkdirhier(dirname(buf)) == -1)
+ {
+ if (pathname)
+ {
+ free(pathname);
+ }
return -1;
+ }
#ifdef DEBUG
printf(" ==> extracting: %s (mode %04o, directory)\n", filename,
@@ -581,6 +769,10 @@ tar_extract_dir(TAR *t, char *realname)
#ifdef DEBUG
perror("chmod()");
#endif
+ if (pathname)
+ {
+ free(pathname);
+ }
return -1;
}
else
@@ -588,6 +780,10 @@ tar_extract_dir(TAR *t, char *realname)
#ifdef DEBUG
puts(" *** using existing directory");
#endif
+ if (pathname)
+ {
+ free(pathname);
+ }
return 1;
}
}
@@ -596,10 +792,18 @@ tar_extract_dir(TAR *t, char *realname)
#ifdef DEBUG
perror("mkdir()");
#endif
+ if (pathname)
+ {
+ free(pathname);
+ }
return -1;
}
}
+ if (pathname)
+ {
+ free(pathname);
+ }
return 0;
}
@@ -611,6 +815,7 @@ tar_extract_fifo(TAR *t, char *realname)
mode_t mode;
char *filename;
char buf[T_BLOCKSIZE];
+ char *pathname = 0;
if (!TH_ISFIFO(t))
{
@@ -618,7 +823,15 @@ tar_extract_fifo(TAR *t, char *realname)
return -1;
}
- filename = (realname ? realname : th_get_pathname(t));
+ if (realname)
+ {
+ filename = realname;
+ }
+ else
+ {
+ pathname = th_get_pathname(t);
+ filename = pathname;
+ }
mode = th_get_mode(t);
/* Make a copy of the string because dirname and mkdirhier may modify the
@@ -627,7 +840,13 @@ tar_extract_fifo(TAR *t, char *realname)
buf[sizeof(buf)-1] = 0;
if (mkdirhier(dirname(buf)) == -1)
+ {
+ if (pathname)
+ {
+ free(pathname);
+ }
return -1;
+ }
#ifdef DEBUG
printf(" ==> extracting: %s (fifo)\n", filename);
@@ -641,10 +860,16 @@ tar_extract_fifo(TAR *t, char *realname)
#ifdef DEBUG
perror("mkfifo()");
#endif
+ if (pathname)
+ {
+ free(pathname);
+ }
return -1;
}
+ if (pathname)
+ {
+ free(pathname);
+ }
return 0;
}
-
-
diff --git a/Utilities/cmtar/output.c b/Utilities/cmtar/output.c
index 38cf157..a60cde2 100644
--- a/Utilities/cmtar/output.c
+++ b/Utilities/cmtar/output.c
@@ -76,6 +76,7 @@ th_print_long_ls(TAR *t)
char groupname[_POSIX_LOGIN_NAME_MAX];
time_t mtime;
struct tm *mtm;
+ char *pathname = 0;
#ifdef HAVE_STRFTIME
char timebuf[18];
@@ -124,7 +125,12 @@ th_print_long_ls(TAR *t)
mtm->tm_mday, mtm->tm_hour, mtm->tm_min, mtm->tm_year + 1900);
#endif
- printf(" %s", th_get_pathname(t));
+ pathname = th_get_pathname(t);
+ if (pathname)
+ {
+ printf(" %s", pathname);
+ free(pathname);
+ }
#if !defined(_WIN32) || defined(__CYGWIN__)
if (TH_ISSYM(t) || TH_ISLNK(t))
@@ -142,5 +148,3 @@ th_print_long_ls(TAR *t)
putchar('\n');
}
-
-
diff --git a/Utilities/cmtar/wrapper.c b/Utilities/cmtar/wrapper.c
index 8f682c2..e82b96e 100644
--- a/Utilities/cmtar/wrapper.c
+++ b/Utilities/cmtar/wrapper.c
@@ -39,24 +39,49 @@ tar_extract_glob(TAR *t, char *globname, char *prefix)
char *filename;
char buf[TAR_MAXPATHLEN];
int i;
+ char *pathname = 0;
while ((i = th_read(t)) == 0)
{
- filename = th_get_pathname(t);
+ pathname = th_get_pathname(t);
+ filename = pathname;
+
if (fnmatch(globname, filename, FNM_PATHNAME | FNM_PERIOD))
{
+ if (pathname)
+ {
+ free(pathname);
+ pathname = 0;
+ }
+
if (TH_ISREG(t) && tar_skip_regfile(t))
return -1;
continue;
}
+
if (t->options & TAR_VERBOSE)
th_print_long_ls(t);
+
if (prefix != NULL)
snprintf(buf, sizeof(buf), "%s/%s", prefix, filename);
else
strlcpy(buf, filename, sizeof(buf));
+
if (tar_extract_file(t, filename) != 0)
+ {
+ if (pathname)
+ {
+ free(pathname);
+ pathname = 0;
+ }
return -1;
+ }
+
+ if (pathname)
+ {
+ free(pathname);
+ pathname = 0;
+ }
}
return (i == 1 ? 0 : -1);
@@ -69,6 +94,7 @@ tar_extract_all(TAR *t, char *prefix)
char *filename;
char buf[TAR_MAXPATHLEN];
int i;
+ char *pathname = 0;
#ifdef DEBUG
printf("==> tar_extract_all(TAR *t, \"%s\")\n",
@@ -80,17 +106,28 @@ tar_extract_all(TAR *t, char *prefix)
#ifdef DEBUG
puts(" tar_extract_all(): calling th_get_pathname()");
#endif
- filename = th_get_pathname(t);
+
+ pathname = th_get_pathname(t);
+ filename = pathname;
+
if (t->options & TAR_VERBOSE)
th_print_long_ls(t);
if (prefix != NULL)
snprintf(buf, sizeof(buf), "%s/%s", prefix, filename);
else
strlcpy(buf, filename, sizeof(buf));
+
+ if (pathname)
+ {
+ free(pathname);
+ pathname = 0;
+ }
+
#ifdef DEBUG
printf(" tar_extract_all(): calling tar_extract_file(t, "
"\"%s\")\n", buf);
#endif
+
if (tar_extract_file(t, buf) != 0)
return -1;
}