Skip to content

Commit 014bcbe

Browse files
committed
fix zipx
1 parent 029c84c commit 014bcbe

1 file changed

Lines changed: 11 additions & 9 deletions

File tree

internal/zipx/zipx.go

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ func Unzip(srcZip, destDir string, p Policy) (err error) {
8484
return err
8585
}
8686

87+
destReal := destAbs
88+
if dr, err := filepath.EvalSymlinks(destAbs); err == nil && dr != "" {
89+
destReal = dr
90+
}
91+
8792
if p.MaxFiles > 0 && len(r.File) > p.MaxFiles {
8893
return fmt.Errorf("zip too many files: %d", len(r.File))
8994
}
@@ -129,8 +134,8 @@ func Unzip(srcZip, destDir string, p Policy) (err error) {
129134
if err != nil {
130135
return err
131136
}
132-
// must be within destAbs
133-
if targetAbs != destAbs && !strings.HasPrefix(targetAbs, destAbs+string(filepath.Separator)) {
137+
// must be within destReal
138+
if targetAbs != destReal && !strings.HasPrefix(targetAbs, destReal+string(filepath.Separator)) {
134139
return fmt.Errorf("unsafe path escape: %q", f.Name)
135140
}
136141

@@ -153,7 +158,7 @@ func Unzip(srcZip, destDir string, p Policy) (err error) {
153158
}
154159

155160
// Parents must not contain symlinks that leave dest, ALWAYS check
156-
if bad, derr := pathHasSymlinkOutside(destAbs, targetAbs); derr == nil && bad {
161+
if bad, derr := pathHasSymlinkOutside(destReal, targetAbs); derr == nil && bad {
157162
return fmt.Errorf("unsafe symlink in parents for: %q", f.Name)
158163
} else if derr != nil && !os.IsNotExist(derr) { // not-exist is fine mid-extract
159164
return derr
@@ -203,22 +208,19 @@ func Unzip(srcZip, destDir string, p Policy) (err error) {
203208
parentResolved = filepath.Dir(targetAbs)
204209
}
205210
linkAbs := filepath.Join(parentResolved, filepath.Base(targetAbs))
206-
if !isPathWithinBase(destAbs, linkAbs) {
211+
if !isPathWithinBase(destReal, linkAbs) {
207212
return fmt.Errorf("symlink destination escapes extraction root: %q", linkAbs)
208213
}
209214
// 2. Where would the symlink, if created, point to? (Relative to resolved parent.)
210215
targetCandidate := filepath.Join(parentResolved, linkTarget)
211-
// We can't EvalSymlinks on the new symlink yet, but check that the _synthetic resolution_ is within destAbs.
212-
if !isPathWithinBase(destAbs, targetCandidate) {
216+
// We can't EvalSymlinks on the new symlink yet, but check that the _synthetic resolution_ is within destReal.
217+
if !isPathWithinBase(destReal, targetCandidate) {
213218
return fmt.Errorf("symlink target escapes extraction root: %q -> %q", f.Name, linkTarget)
214219
}
215220

216221
if err := os.Symlink(linkTarget, targetAbs); err != nil {
217222
return fmt.Errorf("create symlink: %w", err)
218223
}
219-
if p.PreserveTimes && !f.Modified.IsZero() {
220-
_ = os.Chtimes(targetAbs, f.Modified, f.Modified)
221-
}
222224
continue
223225
}
224226

0 commit comments

Comments
 (0)