Blame SOURCES/libtar-1.2.11-fix-memleak.patch

360332
 lib/decode.c    |    2 +-
360332
 lib/extract.c   |   94 +++++++++++++++++++++++++++++++++++++++++++------------
360332
 lib/handle.c    |    1 +
360332
 lib/wrapper.c   |   12 ++++++-
360332
 libtar/libtar.c |   30 +++++++++++------
360332
 5 files changed, 106 insertions(+), 33 deletions(-)
360332
360332
diff --git a/lib/decode.c b/lib/decode.c
360332
index 794c868..c2c2baa 100644
360332
--- a/lib/decode.c
360332
+++ b/lib/decode.c
360332
@@ -29,7 +29,7 @@ th_get_pathname(TAR *t)
360332
 	char filename[MAXPATHLEN];
360332
 
360332
 	if (t->th_buf.gnu_longname)
360332
-		return t->th_buf.gnu_longname;
360332
+		return strdup(t->th_buf.gnu_longname);
360332
 
360332
 	if (t->th_buf.prefix[0] != '\0')
360332
 	{
360332
diff --git a/lib/extract.c b/lib/extract.c
360332
index cacfe58..8993b95 100644
360332
--- a/lib/extract.c
360332
+++ b/lib/extract.c
360332
@@ -44,9 +44,10 @@ tar_set_file_perms(TAR *t, char *realname)
360332
 	uid_t uid;
360332
 	gid_t gid;
360332
 	struct utimbuf ut;
360332
-	char *filename;
360332
+	char *filename,*pn;
360332
 
360332
-	filename = (realname ? realname : th_get_pathname(t));
360332
+	pn = th_get_pathname(t);
360332
+	filename = (realname ? realname : pn);
360332
 	mode = th_get_mode(t);
360332
 	uid = th_get_uid(t);
360332
 	gid = th_get_gid(t);
360332
@@ -69,6 +70,7 @@ tar_set_file_perms(TAR *t, char *realname)
360332
 				filename, uid, gid, strerror(errno));
360332
 # endif
360332
 #endif /* HAVE_LCHOWN */
360332
+			free (pn);
360332
 			return -1;
360332
 		}
360332
 
360332
@@ -78,6 +80,7 @@ tar_set_file_perms(TAR *t, char *realname)
360332
 #ifdef DEBUG
360332
 		perror("utime()");
360332
 #endif
360332
+		free (pn);
360332
 		return -1;
360332
 	}
360332
 
360332
@@ -87,9 +90,11 @@ tar_set_file_perms(TAR *t, char *realname)
360332
 #ifdef DEBUG
360332
 		perror("chmod()");
360332
 #endif
360332
+		free (pn);
360332
 		return -1;
360332
 	}
360332
 
360332
+	free (pn);
360332
 	return 0;
360332
 }
360332
 
360332
@@ -168,7 +173,7 @@ tar_extract_regfile(TAR *t, char *realname)
360332
 	int fdout;
360332
 	int i, k;
360332
 	char buf[T_BLOCKSIZE];
360332
-	char *filename;
360332
+	char *filename,*pn;
360332
 
360332
 #ifdef DEBUG
360332
 	printf("==> tar_extract_regfile(t=0x%lx, realname=\"%s\")\n", t,
360332
@@ -181,14 +186,18 @@ tar_extract_regfile(TAR *t, char *realname)
360332
 		return -1;
360332
 	}
360332
 
360332
-	filename = (realname ? realname : th_get_pathname(t));
360332
+	pn = th_get_pathname(t);
360332
+	filename = (realname ? realname : pn);
360332
 	mode = th_get_mode(t);
360332
 	size = th_get_size(t);
360332
 	uid = th_get_uid(t);
360332
 	gid = th_get_gid(t);
360332
 
360332
 	if (mkdirhier(dirname(filename)) == -1)
360332
+	{
360332
+		free (pn);
360332
 		return -1;
360332
+	}
360332
 
360332
 #ifdef DEBUG
360332
 	printf("  ==> extracting: %s (mode %04o, uid %d, gid %d, %d bytes)\n",
360332
@@ -204,6 +213,7 @@ tar_extract_regfile(TAR *t, char *realname)
360332
 #ifdef DEBUG
360332
 		perror("open()");
360332
 #endif
360332
+		free (pn);
360332
 		return -1;
360332
 	}
360332
 
360332
@@ -235,23 +245,30 @@ tar_extract_regfile(TAR *t, char *realname)
360332
 		{
360332
 			if (k != -1)
360332
 				errno = EINVAL;
360332
+			free (pn);
360332
 			return -1;
360332
 		}
360332
 
360332
 		/* write block to output file */
360332
 		if (write(fdout, buf,
360332
 			  ((i > T_BLOCKSIZE) ? T_BLOCKSIZE : i)) == -1)
360332
+		{
360332
+			free (pn);
360332
 			return -1;
360332
+		}
360332
 	}
360332
 
360332
 	/* close output file */
360332
 	if (close(fdout) == -1)
360332
+	{
360332
+		free (pn);
360332
 		return -1;
360332
+	}
360332
 
360332
 #ifdef DEBUG
360332
 	printf("### done extracting %s\n", filename);
360332
 #endif
360332
-
360332
+	free (pn);
360332
 	return 0;
360332
 }
360332
 
360332
@@ -290,7 +307,7 @@ tar_skip_regfile(TAR *t)
360332
 int
360332
 tar_extract_hardlink(TAR * t, char *realname)
360332
 {
360332
-	char *filename;
360332
+	char *filename,*pn;
360332
 	char *linktgt = NULL;
360332
 	linkname_t *lnp;
360332
 	libtar_hashptr_t hp;
360332
@@ -301,9 +318,13 @@ tar_extract_hardlink(TAR * t, char *realname)
360332
 		return -1;
360332
 	}
360332
 
360332
-	filename = (realname ? realname : th_get_pathname(t));
360332
+	pn = th_get_pathname(t);
360332
+	filename = (realname ? realname : pn);
360332
 	if (mkdirhier(dirname(filename)) == -1)
360332
+	{
360332
+		free (pn);
360332
 		return -1;
360332
+	}
360332
 	libtar_hashptr_reset(&hp;;
360332
 	if (libtar_hash_getkey(t->h, &hp, th_get_linkname(t),
360332
 			       (libtar_matchfunc_t)libtar_str_match) != 0)
360332
@@ -322,9 +343,11 @@ tar_extract_hardlink(TAR * t, char *realname)
360332
 #ifdef DEBUG
360332
 		perror("link()");
360332
 #endif
360332
+		free (pn);
360332
 		return -1;
360332
 	}
360332
 
360332
+	free (pn);
360332
 	return 0;
360332
 }
360332
 
360332
@@ -333,7 +356,7 @@ tar_extract_hardlink(TAR * t, char *realname)
360332
 int
360332
 tar_extract_symlink(TAR *t, char *realname)
360332
 {
360332
-	char *filename;
360332
+	char *filename,*pn;
360332
 
360332
 	if (!TH_ISSYM(t))
360332
 	{
360332
@@ -341,9 +364,13 @@ tar_extract_symlink(TAR *t, char *realname)
360332
 		return -1;
360332
 	}
360332
 
360332
-	filename = (realname ? realname : th_get_pathname(t));
360332
+	pn = th_get_pathname(t);
360332
+	filename = (realname ? realname : pn);
360332
 	if (mkdirhier(dirname(filename)) == -1)
360332
+	{
360332
+		free (pn);
360332
 		return -1;
360332
+	}
360332
 
360332
 	if (unlink(filename) == -1 && errno != ENOENT)
360332
 		return -1;
360332
@@ -357,9 +384,11 @@ tar_extract_symlink(TAR *t, char *realname)
360332
 #ifdef DEBUG
360332
 		perror("symlink()");
360332
 #endif
360332
+		free (pn);
360332
 		return -1;
360332
 	}
360332
 
360332
+	free (pn);
360332
 	return 0;
360332
 }
360332
 
360332
@@ -370,7 +399,7 @@ tar_extract_chardev(TAR *t, char *realname)
360332
 {
360332
 	mode_t mode;
360332
 	unsigned long devmaj, devmin;
360332
-	char *filename;
360332
+	char *filename,*pn;
360332
 
360332
 	if (!TH_ISCHR(t))
360332
 	{
360332
@@ -378,14 +407,18 @@ tar_extract_chardev(TAR *t, char *realname)
360332
 		return -1;
360332
 	}
360332
 
360332
-	filename = (realname ? realname : th_get_pathname(t));
360332
+	pn = th_get_pathname(t);
360332
+	filename = (realname ? realname : pn);
360332
 	mode = th_get_mode(t);
360332
 	devmaj = th_get_devmajor(t);
360332
 	devmin = th_get_devminor(t);
360332
 
360332
 	if (mkdirhier(dirname(filename)) == -1)
360332
+	{
360332
+		free (pn);
360332
 		return -1;
360332
-
360332
+	}
360332
+	
360332
 #ifdef DEBUG
360332
 	printf("  ==> extracting: %s (character device %ld,%ld)\n",
360332
 	       filename, devmaj, devmin);
360332
@@ -396,9 +429,11 @@ tar_extract_chardev(TAR *t, char *realname)
360332
 #ifdef DEBUG
360332
 		perror("mknod()");
360332
 #endif
360332
+		free (pn);
360332
 		return -1;
360332
 	}
360332
 
360332
+	free (pn);
360332
 	return 0;
360332
 }
360332
 
360332
@@ -409,7 +444,7 @@ tar_extract_blockdev(TAR *t, char *realname)
360332
 {
360332
 	mode_t mode;
360332
 	unsigned long devmaj, devmin;
360332
-	char *filename;
360332
+	char *filename,*pn;
360332
 
360332
 	if (!TH_ISBLK(t))
360332
 	{
360332
@@ -417,13 +452,17 @@ tar_extract_blockdev(TAR *t, char *realname)
360332
 		return -1;
360332
 	}
360332
 
360332
-	filename = (realname ? realname : th_get_pathname(t));
360332
+	pn = th_get_pathname(t);
360332
+	filename = (realname ? realname : pn);
360332
 	mode = th_get_mode(t);
360332
 	devmaj = th_get_devmajor(t);
360332
 	devmin = th_get_devminor(t);
360332
 
360332
 	if (mkdirhier(dirname(filename)) == -1)
360332
+	{
360332
+		free (pn);
360332
 		return -1;
360332
+	}
360332
 
360332
 #ifdef DEBUG
360332
 	printf("  ==> extracting: %s (block device %ld,%ld)\n",
360332
@@ -435,9 +474,11 @@ tar_extract_blockdev(TAR *t, char *realname)
360332
 #ifdef DEBUG
360332
 		perror("mknod()");
360332
 #endif
360332
+		free (pn);
360332
 		return -1;
360332
 	}
360332
 
360332
+	free (pn);
360332
 	return 0;
360332
 }
360332
 
360332
@@ -447,19 +488,22 @@ int
360332
 tar_extract_dir(TAR *t, char *realname)
360332
 {
360332
 	mode_t mode;
360332
-	char *filename;
360332
+	char *filename,*pn;
360332
 
360332
 	if (!TH_ISDIR(t))
360332
 	{
360332
 		errno = EINVAL;
360332
 		return -1;
360332
 	}
360332
-
360332
-	filename = (realname ? realname : th_get_pathname(t));
360332
+	pn = th_get_pathname(t);
360332
+	filename = (realname ? realname : pn);
360332
 	mode = th_get_mode(t);
360332
 
360332
 	if (mkdirhier(dirname(filename)) == -1)
360332
+	{
360332
+		free (pn);
360332
 		return -1;
360332
+	}
360332
 
360332
 #ifdef DEBUG
360332
 	printf("  ==> extracting: %s (mode %04o, directory)\n", filename,
360332
@@ -474,6 +518,7 @@ tar_extract_dir(TAR *t, char *realname)
360332
 #ifdef DEBUG
360332
 				perror("chmod()");
360332
 #endif
360332
+				free (pn);
360332
 				return -1;
360332
 			}
360332
 			else
360332
@@ -481,6 +526,7 @@ tar_extract_dir(TAR *t, char *realname)
360332
 #ifdef DEBUG
360332
 				puts("  *** using existing directory");
360332
 #endif
360332
+				free (pn);
360332
 				return 1;
360332
 			}
360332
 		}
360332
@@ -489,10 +535,12 @@ tar_extract_dir(TAR *t, char *realname)
360332
 #ifdef DEBUG
360332
 			perror("mkdir()");
360332
 #endif
360332
+			free (pn);
360332
 			return -1;
360332
 		}
360332
 	}
360332
-
360332
+	
360332
+	free (pn);
360332
 	return 0;
360332
 }
360332
 
360332
@@ -502,7 +550,7 @@ int
360332
 tar_extract_fifo(TAR *t, char *realname)
360332
 {
360332
 	mode_t mode;
360332
-	char *filename;
360332
+	char *filename,*pn;
360332
 
360332
 	if (!TH_ISFIFO(t))
360332
 	{
360332
@@ -510,11 +558,15 @@ tar_extract_fifo(TAR *t, char *realname)
360332
 		return -1;
360332
 	}
360332
 
360332
-	filename = (realname ? realname : th_get_pathname(t));
360332
+	pn = th_get_pathname(t);
360332
+	filename = (realname ? realname : pn);
360332
 	mode = th_get_mode(t);
360332
 
360332
 	if (mkdirhier(dirname(filename)) == -1)
360332
+	{
360332
+		free (pn);
360332
 		return -1;
360332
+	}
360332
 
360332
 #ifdef DEBUG
360332
 	printf("  ==> extracting: %s (fifo)\n", filename);
360332
@@ -524,9 +576,11 @@ tar_extract_fifo(TAR *t, char *realname)
360332
 #ifdef DEBUG
360332
 		perror("mkfifo()");
360332
 #endif
360332
+		free (pn);
360332
 		return -1;
360332
 	}
360332
 
360332
+	free (pn);
360332
 	return 0;
360332
 }
360332
 
360332
diff --git a/lib/handle.c b/lib/handle.c
360332
index ae974b9..e3a48cb 100644
360332
--- a/lib/handle.c
360332
+++ b/lib/handle.c
360332
@@ -82,6 +82,7 @@ tar_open(TAR **t, char *pathname, tartype_t *type,
360332
 	(*t)->fd = (*((*t)->type->openfunc))(pathname, oflags, mode);
360332
 	if ((*t)->fd == -1)
360332
 	{
360332
+		libtar_hash_free((*t)->h, NULL);
360332
 		free(*t);
360332
 		return -1;
360332
 	}
360332
diff --git a/lib/wrapper.c b/lib/wrapper.c
360332
index 51d5086..e60a530 100644
360332
--- a/lib/wrapper.c
360332
+++ b/lib/wrapper.c
360332
@@ -36,7 +36,10 @@ tar_extract_glob(TAR *t, char *globname, char *prefix)
360332
 		if (fnmatch(globname, filename, FNM_PATHNAME | FNM_PERIOD))
360332
 		{
360332
 			if (TH_ISREG(t) && tar_skip_regfile(t))
360332
+			{
360332
+				free (filename);
360332
 				return -1;
360332
+			}
360332
 			continue;
360332
 		}
360332
 		if (t->options & TAR_VERBOSE)
360332
@@ -46,7 +49,11 @@ tar_extract_glob(TAR *t, char *globname, char *prefix)
360332
 		else
360332
 			strlcpy(buf, filename, sizeof(buf));
360332
 		if (tar_extract_file(t, filename) != 0)
360332
+		{
360332
+			free (filename);
360332
 			return -1;
360332
+		}
360332
+		free (filename);
360332
 	}
360332
 
360332
 	return (i == 1 ? 0 : -1);
360332
@@ -77,13 +84,16 @@ tar_extract_all(TAR *t, char *prefix)
360332
 			snprintf(buf, sizeof(buf), "%s/%s", prefix, filename);
360332
 		else
360332
 			strlcpy(buf, filename, sizeof(buf));
360332
-		free(filename);
360332
 #ifdef DEBUG
360332
 		printf("    tar_extract_all(): calling tar_extract_file(t, "
360332
 		       "\"%s\")\n", buf);
360332
 #endif
360332
 		if (tar_extract_file(t, buf) != 0)
360332
+		{
360332
+			free (filename);
360332
 			return -1;
360332
+		}
360332
+		free (filename);
360332
 	}
360332
 
360332
 	return (i == 1 ? 0 : -1);
360332
diff --git a/libtar/libtar.c b/libtar/libtar.c
360332
index a6cef72..f06c5b8 100644
360332
--- a/libtar/libtar.c
360332
+++ b/libtar/libtar.c
360332
@@ -249,7 +249,9 @@ extract(char *tarfile, char *rootdir)
360332
 #endif
360332
 	if (tar_extract_all(t, rootdir) != 0)
360332
 	{
360332
+		
360332
 		fprintf(stderr, "tar_extract_all(): %s\n", strerror(errno));
360332
+		tar_close(t);
360332
 		return -1;
360332
 	}
360332
 
360332
@@ -267,12 +269,13 @@ extract(char *tarfile, char *rootdir)
360332
 
360332
 
360332
 void
360332
-usage()
360332
+usage(void *rootdir)
360332
 {
360332
 	printf("Usage: %s [-C rootdir] [-g] [-z] -x|-t filename.tar\n",
360332
 	       progname);
360332
 	printf("       %s [-C rootdir] [-g] [-z] -c filename.tar ...\n",
360332
 	       progname);
360332
+	free(rootdir);
360332
 	exit(-1);
360332
 }
360332
 
360332
@@ -289,6 +292,7 @@ main(int argc, char *argv[])
360332
 	int c;
360332
 	int mode = 0;
360332
 	libtar_list_t *l;
360332
+	int return_code = -2;
360332
 
360332
 	progname = basename(argv[0]);
360332
 
360332
@@ -310,17 +314,17 @@ main(int argc, char *argv[])
360332
 			break;
360332
 		case 'c':
360332
 			if (mode)
360332
-				usage();
360332
+				usage(rootdir);
360332
 			mode = MODE_CREATE;
360332
 			break;
360332
 		case 'x':
360332
 			if (mode)
360332
-				usage();
360332
+				usage(rootdir);
360332
 			mode = MODE_EXTRACT;
360332
 			break;
360332
 		case 't':
360332
 			if (mode)
360332
-				usage();
360332
+				usage(rootdir);
360332
 			mode = MODE_LIST;
360332
 			break;
360332
 #ifdef HAVE_LIBZ
360332
@@ -329,7 +333,7 @@ main(int argc, char *argv[])
360332
 			break;
360332
 #endif /* HAVE_LIBZ */
360332
 		default:
360332
-			usage();
360332
+			usage(rootdir);
360332
 		}
360332
 
360332
 	if (!mode || ((argc - optind) < (mode == MODE_CREATE ? 2 : 1)))
360332
@@ -338,7 +342,7 @@ main(int argc, char *argv[])
360332
 		printf("argc - optind == %d\tmode == %d\n", argc - optind,
360332
 		       mode);
360332
 #endif
360332
-		usage();
360332
+		usage(rootdir);
360332
 	}
360332
 
360332
 #ifdef DEBUG
360332
@@ -348,21 +352,25 @@ main(int argc, char *argv[])
360332
 	switch (mode)
360332
 	{
360332
 	case MODE_EXTRACT:
360332
-		return extract(argv[optind], rootdir);
360332
+		return_code = extract(argv[optind], rootdir);
360332
+		break;
360332
 	case MODE_CREATE:
360332
 		tarfile = argv[optind];
360332
 		l = libtar_list_new(LIST_QUEUE, NULL);
360332
 		for (c = optind + 1; c < argc; c++)
360332
 			libtar_list_add(l, argv[c]);
360332
-		return create(tarfile, rootdir, l);
360332
+		return_code =  create(tarfile, rootdir, l);
360332
+		libtar_list_free (l, NULL);
360332
+		break;
360332
 	case MODE_LIST:
360332
-		return list(argv[optind]);
360332
+		return_code = list(argv[optind]);
360332
+		break;
360332
 	default:
360332
 		break;
360332
 	}
360332
 
360332
-	/* NOTREACHED */
360332
-	return -2;
360332
+	free(rootdir);
360332
+	return return_code;
360332
 }
360332
 
360332