mirror of https://git.tukaani.org/xz.git
xz: Windows: Don't (de)compress to special files like "con" or "nul".
Before this commit, the following writes "foo" to the
console and deletes the input file:
echo foo | xz > con_xz
xz --suffix=_xz --decompress con_xz
It cannot happen without --suffix because names like con.xz
are also special and so attempting to decompress con.xz
(or compress con to con.xz) will already fail when opening
the input file.
Similar thing is possible when compressing. The following
writes to "nul" and the input file "n" is deleted.
echo foo | xz > n
xz --suffix=ul n
Now xz checks if the destination is a special file before
continuing. DOS/DJGPP version had a check for this but
Windows (and OS/2) didn't.
(cherry picked from commit 660c8c29e5
)
This commit is contained in:
parent
3d70e66ecb
commit
1456a9d943
|
@ -914,20 +914,41 @@ io_open_dest_real(file_pair *pair)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TUKLIB_DOSLIKE
|
|
||||||
// dest_st isn't used on DOS-like systems except as a dummy
|
|
||||||
// argument to io_unlink(), so don't fstat() on such systems.
|
|
||||||
if (fstat(pair->dest_fd, &pair->dest_st)) {
|
if (fstat(pair->dest_fd, &pair->dest_st)) {
|
||||||
// If fstat() really fails, we have a safe fallback here.
|
// If fstat() really fails, we have a safe fallback here.
|
||||||
# if defined(__VMS)
|
#if defined(__VMS)
|
||||||
pair->dest_st.st_ino[0] = 0;
|
pair->dest_st.st_ino[0] = 0;
|
||||||
pair->dest_st.st_ino[1] = 0;
|
pair->dest_st.st_ino[1] = 0;
|
||||||
pair->dest_st.st_ino[2] = 0;
|
pair->dest_st.st_ino[2] = 0;
|
||||||
# else
|
#else
|
||||||
pair->dest_st.st_dev = 0;
|
pair->dest_st.st_dev = 0;
|
||||||
pair->dest_st.st_ino = 0;
|
pair->dest_st.st_ino = 0;
|
||||||
# endif
|
#endif
|
||||||
} else if (try_sparse && opt_mode == MODE_DECOMPRESS) {
|
}
|
||||||
|
#if defined(TUKLIB_DOSLIKE) && !defined(__DJGPP__)
|
||||||
|
// Check that the output file is a regular file. We open with O_EXCL
|
||||||
|
// but that doesn't prevent open()/_open() on Windows from opening
|
||||||
|
// files like "con" or "nul".
|
||||||
|
//
|
||||||
|
// With DJGPP this check is done with stat() even before opening
|
||||||
|
// the output file. That method or a variant of it doesn't work on
|
||||||
|
// Windows because on Windows stat()/_stat64() sets st.st_mode so
|
||||||
|
// that S_ISREG(st.st_mode) will be true even for special files.
|
||||||
|
// With fstat()/_fstat64() it works.
|
||||||
|
else if (pair->dest_fd != STDOUT_FILENO
|
||||||
|
&& !S_ISREG(pair->dest_st.st_mode)) {
|
||||||
|
message_error("%s: Destination is not a regular file",
|
||||||
|
pair->dest_name);
|
||||||
|
|
||||||
|
// dest_fd needs to be reset to -1 to keep io_close() working.
|
||||||
|
(void)close(pair->dest_fd);
|
||||||
|
pair->dest_fd = -1;
|
||||||
|
|
||||||
|
free(pair->dest_name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#elif !defined(TUKLIB_DOSLIKE)
|
||||||
|
else if (try_sparse && opt_mode == MODE_DECOMPRESS) {
|
||||||
// When writing to standard output, we need to be extra
|
// When writing to standard output, we need to be extra
|
||||||
// careful:
|
// careful:
|
||||||
// - It may be connected to something else than
|
// - It may be connected to something else than
|
||||||
|
|
Loading…
Reference in New Issue