Skip to content

fix(archive): keep nested folders in zip preview without directory entries - #3356

Open
Larrtroffen wants to merge 1 commit into
OpenListTeam:mainfrom
Larrtroffen:fix/archive-preview-nested-dirs
Open

Larrtroffen wants to merge 1 commit into
OpenListTeam:mainfrom
Larrtroffen:fix/archive-preview-nested-dirs

Conversation

@Larrtroffen

Copy link
Copy Markdown

Problem

Archive preview drops every sub-directory for zips that do not contain explicit directory entries — which is what python -m zipfile, Python's zipfile module and many CI packers produce (only file entries such as task/environment/Dockerfile).

For a 157-file archive with 10 top-level folders:

  • POST /api/fs/archive/meta returns only the files that sit directly in the first path segment; folders are missing.
  • POST /api/fs/archive/list with inner_path=/<top-folder> returns only those same files, so the folders can never be reached from the UI.

Zips with explicit directory entries happen to work, which makes it look like a frontend issue.

Root cause

  1. internal/archive/tool/helper.go, GenerateMetaTreeFromFolderTraversal: when a new folder chain is created and an ancestor already exists in dirMap, the loop appends the child to its parent but breaks before attaching the newly created parent to the existing grandparent. The intermediate folder becomes an orphan.

    Minimal case: a/ exists (from a/README.txt), then a/b/c/file.txt arrives: b is created and c appended to it, but b is never appended to a.

  2. internal/archive/zip/zip.go, (*Zip).List: only looks at entries whose dirname equals inner_path; deeper paths are skipped and no intermediate directories are synthesized.

Fix

  • Attach every newly created ancestor until an existing node is reached (and never attach the root to itself).
  • In Zip.List, match entries by inner_path + "/" prefix, and turn the next path segment into a synthesized folder object when the remainder still contains /.
  • Add internal/archive/tool/helper_tree_test.go covering a zip with no directory records.

Verification

import zipfile
with zipfile.ZipFile('t.zip', 'w') as z:
    z.writestr('proj/README.txt', 'x')
    z.writestr('proj/sub/deep/file.txt', 'y')  # no directory entries

Before: proj/sub missing. After: proj/sub/deep/file.txt reachable; go test ./internal/archive/... passes.

…tries

Zips produced by Python zipfile/CI packers only contain file entries. Two
places assumed explicit directory entries existed:

- GenerateMetaTreeFromFolderTraversal could orphan a newly created parent
  chain when an ancestor was already known, so folders disappeared from
  the meta tree.
- Zip.List only returned entries whose dirname equalled inner_path, so
  deeper paths and their parent folders were skipped.

Attach every newly created ancestor until an existing node is reached, and
synthesize first-level folders in List from the remaining path prefix.
Adds a regression test for archives without directory records.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant