master hovercats/oakiss / pkg / openbsd / patch / 0009-pax-Fix-GNU-long-name-handling-with-short-read.patch
  1From f88fb1145beac6cce7012b506579d23e0b9826a2 Mon Sep 17 00:00:00 2001
  2From: Michael Forney <mforney@mforney.org>
  3Date: Sat, 3 Dec 2016 20:49:24 -0800
  4Subject: [PATCH] pax: Fix GNU long name handling with short read
  5
  6---
  7 bin/pax/ar_subs.c   | 66 +++++++++++++++++++++++++++++++++------------
  8 bin/pax/buf_subs.c  |  4 +--
  9 bin/pax/file_subs.c | 25 +----------------
 10 3 files changed, 51 insertions(+), 44 deletions(-)
 11
 12diff --git a/bin/pax/ar_subs.c b/bin/pax/ar_subs.c
 13index f018108af59..4c49efa1362 100644
 14--- a/bin/pax/ar_subs.c
 15+++ b/bin/pax/ar_subs.c
 16@@ -37,6 +37,7 @@
 17 #include <sys/types.h>
 18 #include <sys/stat.h>
 19 #include <sys/time.h>
 20+#include <err.h>
 21 #include <errno.h>
 22 #include <fcntl.h>
 23 #include <signal.h>
 24@@ -51,6 +52,7 @@
 25 static void wr_archive(ARCHD *, int is_app);
 26 static int get_arc(void);
 27 static int next_head(ARCHD *);
 28+static int rd_gnu_string(ARCHD *);
 29 extern sigset_t s_mask;
 30 
 31 /*
 32@@ -93,16 +95,8 @@ list(void)
 33 	 * step through the archive until the format says it is done
 34 	 */
 35 	while (next_head(arcn) == 0) {
 36-		if (arcn->type == PAX_GLL || arcn->type == PAX_GLF) {
 37-			/*
 38-			 * we need to read, to get the real filename
 39-			 */
 40-			off_t cnt;
 41-			if (!rd_wrfile(arcn, arcn->type == PAX_GLF
 42-			    ? -1 : -2, &cnt))
 43-				(void)rd_skip(cnt + arcn->pad);
 44+		if (rd_gnu_string(arcn))
 45 			continue;
 46-		}
 47 
 48 		/*
 49 		 * check for pattern, and user specified options match.
 50@@ -245,15 +239,8 @@ extract(void)
 51 	 * says it is done
 52 	 */
 53 	while (next_head(arcn) == 0) {
 54-		if (arcn->type == PAX_GLL || arcn->type == PAX_GLF) {
 55-			/*
 56-			 * we need to read, to get the real filename
 57-			 */
 58-			if (!rd_wrfile(arcn, arcn->type == PAX_GLF
 59-			    ? -1 : -2, &cnt))
 60-				(void)rd_skip(cnt + arcn->pad);
 61+		if (rd_gnu_string(arcn))
 62 			continue;
 63-		}
 64 
 65 		/*
 66 		 * check for pattern, and user specified options match. When
 67@@ -1282,3 +1269,48 @@ get_arc(void)
 68 	paxwarn(1, "Sorry, unable to determine archive format.");
 69 	return(-1);
 70 }
 71+
 72+/*
 73+ * rd_gnu_string()
 74+ * 	Read the file contents into an allocated string if it is a GNU tar
 75+ * 	long link/file.
 76+ * Return:
 77+ * 	1 if gnu string read, 0 otherwise
 78+ */
 79+
 80+static int
 81+rd_gnu_string(ARCHD *arcn)
 82+{
 83+	char **strp;
 84+
 85+	switch (arcn->type) {
 86+	case PAX_GLF:
 87+		strp = &gnu_name_string;
 88+		break;
 89+	case PAX_GLL:
 90+		strp = &gnu_link_string;
 91+		break;
 92+	default:
 93+		strp = NULL;
 94+		break;
 95+	}
 96+	if (!strp)
 97+		return 0;
 98+	/*
 99+	 * we need to read, to get the real filename
100+	 */
101+	if (*strp)
102+		err(1, "WARNING! Major Internal Error! GNU hack Failing!");
103+	*strp = malloc(arcn->sb.st_size + 1);
104+	if (*strp == NULL) {
105+		paxwarn(1, "Out of memory");
106+		(void)rd_skip(arcn->skip + arcn->pad);
107+	} else if (rd_wrbuf(*strp, arcn->sb.st_size) < arcn->sb.st_size) {
108+		free(*strp);
109+		*strp = NULL;
110+	} else {
111+		(*strp)[arcn->sb.st_size] = '\0';
112+		(void)rd_skip(arcn->pad);
113+	}
114+	return 1;
115+}
116diff --git a/bin/pax/buf_subs.c b/bin/pax/buf_subs.c
117index 25dfed5b69b..e3e22a09cc6 100644
118--- a/bin/pax/buf_subs.c
119+++ b/bin/pax/buf_subs.c
120@@ -676,9 +676,7 @@ rd_wrfile(ARCHD *arcn, int ofd, off_t *left)
121 	 * pass the blocksize of the file being written to the write routine,
122 	 * if the size is zero, use the default MINFBSZ
123 	 */
124-	if (ofd < 0)
125-		sz = PAXPATHLEN + 1;		/* GNU tar long link/file */
126-	else if (fstat(ofd, &sb) == 0) {
127+	if (fstat(ofd, &sb) == 0) {
128 		if (sb.st_blksize > 0)
129 			sz = (int)sb.st_blksize;
130 	} else
131diff --git a/bin/pax/file_subs.c b/bin/pax/file_subs.c
132index 9f482480a3b..ae0caf29f6c 100644
133--- a/bin/pax/file_subs.c
134+++ b/bin/pax/file_subs.c
135@@ -924,7 +924,6 @@ file_write(int fd, char *str, int cnt, int *rem, int *isempt, int sz,
136 	char *end;
137 	int wcnt;
138 	char *st = str;
139-	char **strp;
140 
141 	/*
142 	 * while we have data to process
143@@ -983,29 +982,7 @@ file_write(int fd, char *str, int cnt, int *rem, int *isempt, int sz,
144 		/*
145 		 * have non-zero data in this file system block, have to write
146 		 */
147-		switch (fd) {
148-		case -1:
149-			strp = &gnu_name_string;
150-			break;
151-		case -2:
152-			strp = &gnu_link_string;
153-			break;
154-		default:
155-			strp = NULL;
156-			break;
157-		}
158-		if (strp) {
159-			if (*strp)
160-				err(1, "WARNING! Major Internal Error! GNU hack Failing!");
161-			*strp = malloc(wcnt + 1);
162-			if (*strp == NULL) {
163-				paxwarn(1, "Out of memory");
164-				return(-1);
165-			}
166-			memcpy(*strp, st, wcnt);
167-			(*strp)[wcnt] = '\0';
168-			break;
169-		} else if (write(fd, st, wcnt) != wcnt) {
170+		if (write(fd, st, wcnt) != wcnt) {
171 			syswarn(1, errno, "Failed write to file %s", name);
172 			return(-1);
173 		}
174-- 
1752.49.0
176