From b0ffd5a475f87bf4666870fa2e0001e83d4f0092 Mon Sep 17 00:00:00 2001 From: illiliti Date: Wed, 30 Sep 2020 14:15:41 +0300 Subject: [PATCH] Implement StripComponents to rar --- cmd/arc/main.go | 1 + rar.go | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/cmd/arc/main.go b/cmd/arc/main.go index fdb73579..1050cd05 100644 --- a/cmd/arc/main.go +++ b/cmd/arc/main.go @@ -235,6 +235,7 @@ func getFormat(subcommand string) (interface{}, error) { v.OverwriteExisting = overwriteExisting v.MkdirAll = mkdirAll v.ImplicitTopLevelFolder = implicitTopLevelFolder + v.StripComponents = stripComponents v.ContinueOnError = continueOnError v.Password = os.Getenv("ARCHIVE_PASSWORD") case *archiver.Tar: diff --git a/rar.go b/rar.go index 566adef8..56c2a3e3 100644 --- a/rar.go +++ b/rar.go @@ -40,6 +40,10 @@ type Rar struct { // especially on extraction. ImplicitTopLevelFolder bool + // Strip number of leading paths. This feature is available + // only during unpacking of the entire archive. + StripComponents int + // If true, errors encountered during reading // or writing a single file will be logged and // the operation will continue on remaining files. @@ -168,6 +172,17 @@ func (r *Rar) unrarNext(to string) error { return fmt.Errorf("checking path traversal attempt: %v", errPath) } + if r.StripComponents > 0 { + if strings.Count(header.Name, "/") < r.StripComponents { + return nil // skip path with fewer components + } + + for i := 0; i < r.StripComponents; i++ { + slash := strings.Index(header.Name, "/") + header.Name = header.Name[slash+1:] + } + } + return r.unrarFile(f, filepath.Join(to, header.Name)) }