Handle symlink zip files (#5249)

This commit is contained in:
WithoutPants 2024-09-11 13:58:02 +10:00 committed by GitHub
parent d1c207e40b
commit a17199ba21
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 18 additions and 17 deletions

View file

@ -58,13 +58,8 @@ func (f *OsFS) Open(name string) (fs.ReadDirFile, error) {
return os.Open(name) return os.Open(name)
} }
func (f *OsFS) OpenZip(name string) (models.ZipFS, error) { func (f *OsFS) OpenZip(name string, size int64) (models.ZipFS, error) {
info, err := f.Lstat(name) return newZipFS(f, name, size)
if err != nil {
return nil, err
}
return newZipFS(f, name, info)
} }
func (f *OsFS) IsPathCaseSensitive(path string) (bool, error) { func (f *OsFS) IsPathCaseSensitive(path string) (bool, error) {

View file

@ -341,7 +341,7 @@ func (s *scanJob) acceptEntry(ctx context.Context, path string, info fs.FileInfo
} }
func (s *scanJob) scanZipFile(ctx context.Context, f scanFile) error { func (s *scanJob) scanZipFile(ctx context.Context, f scanFile) error {
zipFS, err := f.fs.OpenZip(f.Path) zipFS, err := f.fs.OpenZip(f.Path, f.Size)
if err != nil { if err != nil {
if errors.Is(err, errNotReaderAt) { if errors.Is(err, errNotReaderAt) {
// can't walk the zip file // can't walk the zip file
@ -838,7 +838,7 @@ func (s *scanJob) getFileFS(f *models.BaseFile) (models.FS, error) {
} }
zipPath := f.ZipFile.Base().Path zipPath := f.ZipFile.Base().Path
return fs.OpenZip(zipPath) return fs.OpenZip(zipPath, f.Size)
} }
func (s *scanJob) handleRename(ctx context.Context, f models.File, fp []models.Fingerprint) (models.File, error) { func (s *scanJob) handleRename(ctx context.Context, f models.File, fp []models.Fingerprint) (models.File, error) {

View file

@ -26,11 +26,10 @@ var (
type zipFS struct { type zipFS struct {
*zip.Reader *zip.Reader
zipFileCloser io.Closer zipFileCloser io.Closer
zipInfo fs.FileInfo
zipPath string zipPath string
} }
func newZipFS(fs models.FS, path string, info fs.FileInfo) (*zipFS, error) { func newZipFS(fs models.FS, path string, size int64) (*zipFS, error) {
reader, err := fs.Open(path) reader, err := fs.Open(path)
if err != nil { if err != nil {
return nil, err return nil, err
@ -42,7 +41,7 @@ func newZipFS(fs models.FS, path string, info fs.FileInfo) (*zipFS, error) {
return nil, errNotReaderAt return nil, errNotReaderAt
} }
zipReader, err := zip.NewReader(asReaderAt, info.Size()) zipReader, err := zip.NewReader(asReaderAt, size)
if err != nil { if err != nil {
reader.Close() reader.Close()
return nil, err return nil, err
@ -89,7 +88,6 @@ func newZipFS(fs models.FS, path string, info fs.FileInfo) (*zipFS, error) {
return &zipFS{ return &zipFS{
Reader: zipReader, Reader: zipReader,
zipFileCloser: reader, zipFileCloser: reader,
zipInfo: info,
zipPath: path, zipPath: path,
}, nil }, nil
} }
@ -125,7 +123,7 @@ func (f *zipFS) Lstat(name string) (fs.FileInfo, error) {
return f.Stat(name) return f.Stat(name)
} }
func (f *zipFS) OpenZip(name string) (models.ZipFS, error) { func (f *zipFS) OpenZip(name string, size int64) (models.ZipFS, error) {
return nil, errZipFSOpenZip return nil, errZipFSOpenZip
} }

View file

@ -15,7 +15,7 @@ type FS interface {
Stat(name string) (fs.FileInfo, error) Stat(name string) (fs.FileInfo, error)
Lstat(name string) (fs.FileInfo, error) Lstat(name string) (fs.FileInfo, error)
Open(name string) (fs.ReadDirFile, error) Open(name string) (fs.ReadDirFile, error)
OpenZip(name string) (ZipFS, error) OpenZip(name string, size int64) (ZipFS, error)
IsPathCaseSensitive(path string) (bool, error) IsPathCaseSensitive(path string) (bool, error)
} }

View file

@ -93,7 +93,7 @@ type DirEntry struct {
func (e *DirEntry) info(fs FS, path string) (fs.FileInfo, error) { func (e *DirEntry) info(fs FS, path string) (fs.FileInfo, error) {
if e.ZipFile != nil { if e.ZipFile != nil {
zipPath := e.ZipFile.Base().Path zipPath := e.ZipFile.Base().Path
zfs, err := fs.OpenZip(zipPath) zfs, err := fs.OpenZip(zipPath, e.ZipFile.Base().Size)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -163,7 +163,7 @@ func (f *BaseFile) Base() *BaseFile {
func (f *BaseFile) Open(fs FS) (io.ReadCloser, error) { func (f *BaseFile) Open(fs FS) (io.ReadCloser, error) {
if f.ZipFile != nil { if f.ZipFile != nil {
zipPath := f.ZipFile.Base().Path zipPath := f.ZipFile.Base().Path
zfs, err := fs.OpenZip(zipPath) zfs, err := fs.OpenZip(zipPath, f.ZipFile.Base().Size)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -178,6 +178,7 @@ type fileQueryRow struct {
ZipBasename null.String `db:"zip_basename"` ZipBasename null.String `db:"zip_basename"`
ZipFolderPath null.String `db:"zip_folder_path"` ZipFolderPath null.String `db:"zip_folder_path"`
ZipSize null.Int `db:"zip_size"`
FolderPath null.String `db:"parent_folder_path"` FolderPath null.String `db:"parent_folder_path"`
fingerprintQueryRow fingerprintQueryRow
@ -205,6 +206,7 @@ func (r *fileQueryRow) resolve() models.File {
ID: *basic.ZipFileID, ID: *basic.ZipFileID,
Path: filepath.Join(r.ZipFolderPath.String, r.ZipBasename.String), Path: filepath.Join(r.ZipFolderPath.String, r.ZipBasename.String),
Basename: r.ZipBasename.String, Basename: r.ZipBasename.String,
Size: r.ZipSize.Int64,
} }
} }
@ -461,6 +463,8 @@ func (qb *FileStore) selectDataset() *goqu.SelectDataset {
fingerprintTable.Col("fingerprint"), fingerprintTable.Col("fingerprint"),
zipFileTable.Col("basename").As("zip_basename"), zipFileTable.Col("basename").As("zip_basename"),
zipFolderTable.Col("path").As("zip_folder_path"), zipFolderTable.Col("path").As("zip_folder_path"),
// size is needed to open containing zip files
zipFileTable.Col("size").As("zip_size"),
} }
cols = append(cols, videoFileQueryColumns()...) cols = append(cols, videoFileQueryColumns()...)

View file

@ -41,6 +41,7 @@ type folderQueryRow struct {
ZipBasename null.String `db:"zip_basename"` ZipBasename null.String `db:"zip_basename"`
ZipFolderPath null.String `db:"zip_folder_path"` ZipFolderPath null.String `db:"zip_folder_path"`
ZipSize null.Int `db:"zip_size"`
} }
func (r *folderQueryRow) resolve() *models.Folder { func (r *folderQueryRow) resolve() *models.Folder {
@ -61,6 +62,7 @@ func (r *folderQueryRow) resolve() *models.Folder {
ID: *ret.ZipFileID, ID: *ret.ZipFileID,
Path: filepath.Join(r.ZipFolderPath.String, r.ZipBasename.String), Path: filepath.Join(r.ZipFolderPath.String, r.ZipBasename.String),
Basename: r.ZipBasename.String, Basename: r.ZipBasename.String,
Size: r.ZipSize.Int64,
} }
} }
@ -148,6 +150,8 @@ func (qb *FolderStore) selectDataset() *goqu.SelectDataset {
table.Col("updated_at"), table.Col("updated_at"),
zipFileTable.Col("basename").As("zip_basename"), zipFileTable.Col("basename").As("zip_basename"),
zipFolderTable.Col("path").As("zip_folder_path"), zipFolderTable.Col("path").As("zip_folder_path"),
// size is needed to open containing zip files
zipFileTable.Col("size").As("zip_size"),
} }
ret := dialect.From(table).Select(cols...) ret := dialect.From(table).Select(cols...)