Validate zip symlinks and backslash paths before extraction
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/lint Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful

- treat `\` as a separator in safe_relative so `\abs` and `..\..\x` are refused
- read zip symlink targets with `unzip -p` off the `unzip -Z -l` listing and reject escapes before unpacking
This commit is contained in:
2026-09-05 16:59:11 +10:00
parent ca55c9dd9f
commit 6e1b018adb
4 changed files with 227 additions and 44 deletions
+8 -2
View File
@@ -147,14 +147,20 @@ A literal `token` key is rejected at |vimpack-setup| time.
7. LAYOUT *vimpack-layout*
stdpath('cache')/vimpack/archives/ downloaded archives
stdpath('cache')/vimpack/stage/ extraction staging area
stdpath('data')/site/pack/vimpack/.vimpack-stage/ extraction staging area
stdpath('data')/vimpack/manifest.json installed name/version/sha256
stdpath('data')/site/pack/vimpack/start/<name>
stdpath('data')/site/pack/vimpack/opt/<name>
An install extracts to the staging area, hoists a single wrapper directory if
the archive has one, then renames into place after parking any previous tree
aside. If the rename fails the previous tree is restored.
aside. If the rename fails the previous tree is restored. Staging sits under
the pack root so that rename stays on one filesystem.
Every member is listed and validated before extraction: absolute paths, `..`
and `..\` escapes, devices, fifos and links pointing out of the destination
are all refused. Zip symlink targets are read with `unzip -p` (stdout only,
nothing written) because the zip listing does not carry them.
Lazy loading is out of scope: `opt = true` only chooses the opt/ bucket.