| 927 | } |
| 928 | |
| 929 | func readEditableFileHistoryContent(filePath string) ([]byte, os.FileMode, bool) { |
| 930 | info, err := os.Lstat(filePath) |
| 931 | if err != nil { |
| 932 | return nil, 0640, false |
| 933 | } |
| 934 | mode := info.Mode() |
| 935 | if mode.IsDir() || mode&os.ModeSymlink != 0 || !mode.IsRegular() || files.IsBlockDevice(mode) || info.Size() > fileHistorySnapshotMaxSize { |
| 936 | return nil, mode, false |
| 937 | } |
| 938 | if files.IsBinaryPreviewFile(files.GetMimeType(filePath), filepath.Ext(info.Name())) { |
| 939 | return nil, mode, false |
| 940 | } |
| 941 | file, err := os.Open(filePath) |
| 942 | if err != nil { |
| 943 | return nil, mode, false |
| 944 | } |
| 945 | defer file.Close() |
| 946 | |
| 947 | headBuf := make([]byte, 1024) |
| 948 | n, err := file.Read(headBuf) |
| 949 | if err != nil && err != io.EOF { |
| 950 | return nil, mode, false |
| 951 | } |
| 952 | if n > 0 && files.DetectBinary(headBuf[:n]) { |
| 953 | return nil, mode, false |
| 954 | } |
| 955 | if _, err := file.Seek(0, 0); err != nil { |
| 956 | return nil, mode, false |
| 957 | } |
| 958 | content, err := io.ReadAll(io.LimitReader(file, fileHistorySnapshotMaxSize+1)) |
| 959 | if err != nil || int64(len(content)) > fileHistorySnapshotMaxSize { |
| 960 | return nil, mode, false |
| 961 | } |
| 962 | return content, mode, true |
| 963 | } |
| 964 | |
| 965 | func buildHistoryMoveTargetPath(dst, name, sourcePath string, sourceCount int) string { |
| 966 | if strings.TrimSpace(dst) == "" { |