package main
import (
"archive/zip"
"log"
"os"
)
const charDeviceFile = "/dev/null"
func main() {
fi, err := os.Stat(charDeviceFile)
if err != nil {
panic(err)
}
fh, err := zip.FileInfoHeader(fi)
if err != nil {
panic(err)
}
if isChar(fi) != isChar(fh.FileInfo()) {
log.Printf("file mode inconsistent after zip.FileInfoHeader: got %q, want %q", fh.FileInfo().Mode(), fi.Mode())
}
}
func isChar(fi os.FileInfo) bool { return fi.Mode() & os.ModeCharDevice != 0 }
This reproducer program fails unexpectedly with the error:
file mode inconsistent after zip.FileInfoHeader: got "-rw-rw-rw-", want "Dcrw-rw-rw-"
The data loss is due to a logically impossible bit match in fileModeToUnixMode. The fix:
--- src/archive/zip/struct.go 2019-12-29 02:26:54.000000000 +0100
+++ src/archive/zip/struct.go 2019-12-29 02:27:05.000000000 +0100
@@ -337,12 +337,10 @@
m = s_IFIFO
case os.ModeSocket:
m = s_IFSOCK
+ case os.ModeDevice | os.ModeCharDevice:
+ m = s_IFCHR
case os.ModeDevice:
- if mode&os.ModeCharDevice != 0 {
- m = s_IFCHR
- } else {
- m = s_IFBLK
- }
+ m = s_IFBLK
}
if mode&os.ModeSetuid != 0 {
m |= s_ISUID
This reproducer program fails unexpectedly with the error:
The data loss is due to a logically impossible bit match in
fileModeToUnixMode. The fix: