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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
$NetBSD: patch-ab,v 1.1.6.1 2005/06/09 22:31:18 salo Exp $
# CAN-2005-1228 and CAN-2005-0988
--- gzip.c.orig 1993-08-19 09:39:00.000000000 +0100
+++ gzip.c
@@ -824,8 +824,11 @@ local void treat_file(iname)
}
close(ifd);
- if (!to_stdout && close(ofd)) {
- write_error();
+ if (!to_stdout) {
+ /* Copy modes, times, ownership, and remove the input file */
+ copy_stat(&istat);
+ if (close(ofd))
+ write_error();
}
if (method == -1) {
if (!to_stdout) unlink (ofname);
@@ -845,10 +848,6 @@ local void treat_file(iname)
}
fprintf(stderr, "\n");
}
- /* Copy modes, times, ownership, and remove the input file */
- if (!to_stdout) {
- copy_stat(&istat);
- }
}
/* ========================================================================
@@ -1005,7 +1004,14 @@ local int get_istat(iname, sbuf)
#ifdef NO_MULTIPLE_DOTS
char *dot; /* pointer to ifname extension, or NULL */
#endif
+ int max_suffix_len = (z_len > 3 ? z_len : 3);
+ /* Leave enough room in ifname or ofname for suffix: */
+ if (strlen(iname) >= sizeof(ifname) - max_suffix_len) {
+ strncpy(ifname, iname, sizeof(ifname) - 1);
+ /* last byte of ifname is already zero and never overwritten */
+ error("file name too long");
+ }
strcpy(ifname, iname);
/* If input file exists, return OK. */
@@ -1244,6 +1250,7 @@ local int get_method(in)
/* Copy the base name. Keep a directory prefix intact. */
char *p = basename(ofname);
char *base = p;
+ char *base2;
for (;;) {
*p = (char)get_char();
if (*p++ == '\0') break;
@@ -1251,6 +1258,8 @@ local int get_method(in)
error("corrupted input -- file name too large");
}
}
+ base2 = basename (base);
+ strcpy(base, base2);
/* If necessary, adapt the name to local OS conventions: */
if (!list) {
MAKE_LEGAL_NAME(base);
@@ -1624,12 +1633,12 @@ local void copy_stat(ifstat)
reset_times(ofname, ifstat);
#endif
/* Copy the protection modes */
- if (chmod(ofname, ifstat->st_mode & 07777)) {
+ if (fchmod(ofd, ifstat->st_mode & 07777)) {
WARN((stderr, "%s: ", progname));
if (!quiet) perror(ofname);
}
#ifndef NO_CHOWN
- chown(ofname, ifstat->st_uid, ifstat->st_gid); /* Copy ownership */
+ (void) fchown(ofd, ifstat->st_uid, ifstat->st_gid); /* Copy ownership */
#endif
remove_ofname = 0;
/* It's now safe to remove the input file: */
|