summaryrefslogtreecommitdiff
path: root/archivers/star/patches/patch-ad
blob: 6f4ba10cb694bd7fdc3629f0b1d81332d7c47c7d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
$NetBSD: patch-ad,v 1.2 2010/09/28 17:50:07 tnn Exp $

--- star/extract.c.orig	2002-05-02 20:02:41.000000000 +0000
+++ star/extract.c
@@ -92,6 +92,7 @@ EXPORT	int	xt_file		__PR((FINFO * info,
 					int (*)(void *, char *, int),
 					void *arg, int amt, char* text));
 EXPORT	void	skip_slash	__PR((FINFO * info));
+LOCAL	BOOL	has_dotdot	__PR((char *name));
 
 EXPORT void
 extract(vhname)
@@ -152,6 +153,12 @@ extract(vhname)
 		if (is_symlink(&finfo) && same_symlink(&finfo)) {
 			continue;
 		}
+		if (!interactive && has_dotdot(finfo.f_name)) {
+			errmsgno(EX_BAD, "'%s' contains '..', skipping ...\n",
+				finfo.f_name);
+			void_file(&finfo);
+			return;
+		}
 		if (interactive && !ia_change(ptb, &finfo)) {
 			if (!nflag)
 				fprintf(vpr, "Skipping ...\n");
@@ -169,6 +176,12 @@ extract(vhname)
 			if (!make_dir(&finfo))
 				continue;
 		} else if (is_link(&finfo)) {
+			if (!interactive && has_dotdot(finfo.f_lname)) {
+				errmsgno(EX_BAD, "'%s' contains '..', "
+					"skipping ...\n", finfo.f_lname);
+				void_file(&finfo);
+				return;
+			}
 			if (!make_link(&finfo))
 				continue;
 		} else if (is_symlink(&finfo)) {
@@ -830,3 +843,25 @@ skip_slash(info)
 	while (info->f_lname[0] == '/')
 		info->f_lname++;
 }
+
+LOCAL BOOL
+has_dotdot(name)
+	char	*name;
+{
+	register char	*p = name;
+
+	while (*p) {
+		if ((p[0] == '.' && p[1] == '.') &&
+		    (p[2] == '/' || p[2] == '\0')) {
+			return (TRUE);
+		}
+		do {
+			if (*p++ == '\0')
+				return (FALSE);
+		} while (*p != '/');
+		p++;
+		while (*p && *p == '/')	/* Skip multiple slashes */
+			p++;
+	}
+	return (FALSE);
+}