From a17199ba216082d1763cac9fd0b24a464dbe0297 Mon Sep 17 00:00:00 2001 From: WithoutPants <53250216+WithoutPants@users.noreply.github.com> Date: Wed, 11 Sep 2024 13:58:02 +1000 Subject: [PATCH] Handle symlink zip files (#5249) --- pkg/file/fs.go | 9 ++------- pkg/file/scan.go | 4 ++-- pkg/file/zip.go | 8 +++----- pkg/models/fs.go | 2 +- pkg/models/model_file.go | 4 ++-- pkg/sqlite/file.go | 4 ++++ pkg/sqlite/folder.go | 4 ++++ 7 files changed, 18 insertions(+), 17 deletions(-) diff --git a/pkg/file/fs.go b/pkg/file/fs.go index 80148cfa1..0311ed5ab 100644 --- a/pkg/file/fs.go +++ b/pkg/file/fs.go @@ -58,13 +58,8 @@ func (f *OsFS) Open(name string) (fs.ReadDirFile, error) { return os.Open(name) } -func (f *OsFS) OpenZip(name string) (models.ZipFS, error) { - info, err := f.Lstat(name) - if err != nil { - return nil, err - } - - return newZipFS(f, name, info) +func (f *OsFS) OpenZip(name string, size int64) (models.ZipFS, error) { + return newZipFS(f, name, size) } func (f *OsFS) IsPathCaseSensitive(path string) (bool, error) { diff --git a/pkg/file/scan.go b/pkg/file/scan.go index fac493080..3cfc4c26b 100644 --- a/pkg/file/scan.go +++ b/pkg/file/scan.go @@ -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 { - zipFS, err := f.fs.OpenZip(f.Path) + zipFS, err := f.fs.OpenZip(f.Path, f.Size) if err != nil { if errors.Is(err, errNotReaderAt) { // 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 - 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) { diff --git a/pkg/file/zip.go b/pkg/file/zip.go index a17b59685..4df2453dc 100644 --- a/pkg/file/zip.go +++ b/pkg/file/zip.go @@ -26,11 +26,10 @@ var ( type zipFS struct { *zip.Reader zipFileCloser io.Closer - zipInfo fs.FileInfo 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) if err != nil { return nil, err @@ -42,7 +41,7 @@ func newZipFS(fs models.FS, path string, info fs.FileInfo) (*zipFS, error) { return nil, errNotReaderAt } - zipReader, err := zip.NewReader(asReaderAt, info.Size()) + zipReader, err := zip.NewReader(asReaderAt, size) if err != nil { reader.Close() return nil, err @@ -89,7 +88,6 @@ func newZipFS(fs models.FS, path string, info fs.FileInfo) (*zipFS, error) { return &zipFS{ Reader: zipReader, zipFileCloser: reader, - zipInfo: info, zipPath: path, }, nil } @@ -125,7 +123,7 @@ func (f *zipFS) Lstat(name string) (fs.FileInfo, error) { 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 } diff --git a/pkg/models/fs.go b/pkg/models/fs.go index bdbf60349..771c7c211 100644 --- a/pkg/models/fs.go +++ b/pkg/models/fs.go @@ -15,7 +15,7 @@ type FS interface { Stat(name string) (fs.FileInfo, error) Lstat(name string) (fs.FileInfo, error) Open(name string) (fs.ReadDirFile, error) - OpenZip(name string) (ZipFS, error) + OpenZip(name string, size int64) (ZipFS, error) IsPathCaseSensitive(path string) (bool, error) } diff --git a/pkg/models/model_file.go b/pkg/models/model_file.go index 45e755474..e9df57990 100644 --- a/pkg/models/model_file.go +++ b/pkg/models/model_file.go @@ -93,7 +93,7 @@ type DirEntry struct { func (e *DirEntry) info(fs FS, path string) (fs.FileInfo, error) { if e.ZipFile != nil { zipPath := e.ZipFile.Base().Path - zfs, err := fs.OpenZip(zipPath) + zfs, err := fs.OpenZip(zipPath, e.ZipFile.Base().Size) if err != nil { return nil, err } @@ -163,7 +163,7 @@ func (f *BaseFile) Base() *BaseFile { func (f *BaseFile) Open(fs FS) (io.ReadCloser, error) { if f.ZipFile != nil { zipPath := f.ZipFile.Base().Path - zfs, err := fs.OpenZip(zipPath) + zfs, err := fs.OpenZip(zipPath, f.ZipFile.Base().Size) if err != nil { return nil, err } diff --git a/pkg/sqlite/file.go b/pkg/sqlite/file.go index 6cd74eb34..6bf6e32b5 100644 --- a/pkg/sqlite/file.go +++ b/pkg/sqlite/file.go @@ -178,6 +178,7 @@ type fileQueryRow struct { ZipBasename null.String `db:"zip_basename"` ZipFolderPath null.String `db:"zip_folder_path"` + ZipSize null.Int `db:"zip_size"` FolderPath null.String `db:"parent_folder_path"` fingerprintQueryRow @@ -205,6 +206,7 @@ func (r *fileQueryRow) resolve() models.File { ID: *basic.ZipFileID, Path: filepath.Join(r.ZipFolderPath.String, r.ZipBasename.String), Basename: r.ZipBasename.String, + Size: r.ZipSize.Int64, } } @@ -461,6 +463,8 @@ func (qb *FileStore) selectDataset() *goqu.SelectDataset { fingerprintTable.Col("fingerprint"), zipFileTable.Col("basename").As("zip_basename"), 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()...) diff --git a/pkg/sqlite/folder.go b/pkg/sqlite/folder.go index 26cbf8962..4cf632d49 100644 --- a/pkg/sqlite/folder.go +++ b/pkg/sqlite/folder.go @@ -41,6 +41,7 @@ type folderQueryRow struct { ZipBasename null.String `db:"zip_basename"` ZipFolderPath null.String `db:"zip_folder_path"` + ZipSize null.Int `db:"zip_size"` } func (r *folderQueryRow) resolve() *models.Folder { @@ -61,6 +62,7 @@ func (r *folderQueryRow) resolve() *models.Folder { ID: *ret.ZipFileID, Path: filepath.Join(r.ZipFolderPath.String, 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"), zipFileTable.Col("basename").As("zip_basename"), 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...)