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);
+}
|