summaryrefslogtreecommitdiffstats
path: root/usr.bin/compress
diff options
context:
space:
mode:
authortrhodes <trhodes@FreeBSD.org>2003-06-14 13:41:31 +0000
committertrhodes <trhodes@FreeBSD.org>2003-06-14 13:41:31 +0000
commit23174ba968d72735a3fdf0b790b14ccabdc40946 (patch)
tree7393e5d31b83afe0cddea6237f8e73918cbda739 /usr.bin/compress
parentd84e6f299c6d13559693af99d2046ebf0b7496a2 (diff)
downloadFreeBSD-src-23174ba968d72735a3fdf0b790b14ccabdc40946.zip
FreeBSD-src-23174ba968d72735a3fdf0b790b14ccabdc40946.tar.gz
Don't truncate the output file before making sure that we can
read at least 1 byte from the input file without problems. This fixes a bug in uncompress(1) that causes the accidental removal of files that happen to have the same name as the output file, even when the uncompression fails and is aborted, i.e.: $ echo hello world > hello $ touch hello.Z $ ls -l hello* -rw-rw-r-- 1 giorgos giorgos 12 Jun 14 13:33 hello -rw-rw-r-- 1 giorgos giorgos 0 Jun 14 13:33 hello.Z $ ./uncompress -f hello uncompress: hello.Z: Inappropriate file type or format $ ls -l hello* -rw-rw-r-- 1 giorgos giorgos 0 Jun 14 13:33 hello.Z $ PR: 46787 Submitted by: keramida
Diffstat (limited to 'usr.bin/compress')
-rw-r--r--usr.bin/compress/compress.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/usr.bin/compress/compress.c b/usr.bin/compress/compress.c
index ceaac87..584f283 100644
--- a/usr.bin/compress/compress.c
+++ b/usr.bin/compress/compress.c
@@ -300,14 +300,9 @@ decompress(const char *in, const char *out, int bits)
isreg = oreg = !exists || S_ISREG(sb.st_mode);
ifp = ofp = NULL;
- if ((ofp = fopen(out, "w")) == NULL) {
- cwarn("%s", out);
- return;
- }
-
if ((ifp = zopen(in, "r", bits)) == NULL) {
cwarn("%s", in);
- goto err;
+ return;
}
if (stat(in, &sb)) {
cwarn("%s", in);
@@ -316,6 +311,22 @@ decompress(const char *in, const char *out, int bits)
if (!S_ISREG(sb.st_mode))
isreg = 0;
+ /*
+ * Try to read the first few uncompressed bytes from the input file
+ * before blindly truncating the output file.
+ */
+ if ((nr = fread(buf, 1, sizeof(buf), ifp)) == 0) {
+ cwarn("%s", in);
+ (void)fclose(ifp);
+ return;
+ }
+ if ((ofp = fopen(out, "w")) == NULL ||
+ (nr != 0 && fwrite(buf, 1, nr, ofp) != nr)) {
+ cwarn("%s", out);
+ (void)fclose(ifp);
+ return;
+ }
+
while ((nr = fread(buf, 1, sizeof(buf), ifp)) != 0)
if (fwrite(buf, 1, nr, ofp) != nr) {
cwarn("%s", out);
OpenPOWER on IntegriCloud