Skip to content

Commit

Permalink
more fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
mpawlowski committed Dec 31, 2023
1 parent b060c7b commit c919f19
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 82 deletions.
2 changes: 1 addition & 1 deletion .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
{
"label": "Dev",
"type": "shell",
"command": "go run main.go --install-dir=work/install --profile-zip=r2modman/testdata/mods-5.r2z --work-dir=work/cache",
"command": "rm -rf work/install && mkdir -p work/install && go run main.go --install-dir=work/install --profile-zip=r2modman/testdata/Xmas_Valheim_v1.2_1704056810687.r2z --work-dir=work/cache",
"problemMatcher": []
}
]
Expand Down
19 changes: 0 additions & 19 deletions Makefile

This file was deleted.

1 change: 0 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,6 @@ func run(

// extract profile to bepinex in install dir
bepinDir := path.Join(options.installDir, "/BepInEx")
log.Printf(fmt.Sprintf("Extracting %s to %s", options.profileZip, bepinDir))
err = extractor.Extract(options.profileZip, bepinDir, "BepInEx")
if err != nil {
return err
Expand Down
Binary file not shown.
2 changes: 1 addition & 1 deletion r2modman/thunderstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,5 @@ func DeterminePackagingType(modZipFilename string) (modType ModPackagingType, pr
}

// assume Plugin by default
return ModPackagingTypePlugin, "", nil
return ModPackagingTypePlugin, "plugins", nil
}
107 changes: 47 additions & 60 deletions zip/extractor.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import (
"archive/zip"
"fmt"
"io"
"log"
"os"
"path"
"path/filepath"
"runtime"
"strings"
)

Expand All @@ -16,81 +19,65 @@ type Extractor interface {
type extractorImpl struct {
}

func (e *extractorImpl) Extract(zipFileName string, destinationDir string, stripPrefix string) error {
func ExtractAndWriteFile(zipEntry *zip.File, normalizedDestination string) error {
if zipEntry.FileInfo().IsDir() {
return nil
}

r, err := zip.OpenReader(zipFileName)
zipReadCloser, err := zipEntry.Open()
if err != nil {
return err
}
defer func() {
if err := r.Close(); err != nil {
panic(err)
}
}()
defer zipReadCloser.Close()

// Closure to address file descriptors issue with all the deferred .Close() methods
extractAndWriteFile := func(zipFile *zip.File, stripPrefix string) error {
zipReadCloser, err := zipFile.Open()
if err != nil {
return err
}
defer func() {
if err := zipReadCloser.Close(); err != nil {
panic(err)
}
}()
// Create the directory path if it doesn't exist
dirPath := filepath.Dir(normalizedDestination)
if err := os.MkdirAll(dirPath, 0755); err != nil {
return fmt.Errorf("unable to create directory '%s': %v", dirPath, err)
}

path := filepath.Join(destinationDir, zipFile.Name)
// Open the file in write-only mode, create if it doesn't exist, truncate otherwise
file, err := os.OpenFile(normalizedDestination, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
return fmt.Errorf("unable to open file '%s': %v", normalizedDestination, err)
}
defer file.Close()

// Check for ZipSlip (Directory traversal)
if !strings.HasPrefix(path, filepath.Clean(destinationDir)+string(os.PathSeparator)) {
return fmt.Errorf("illegal file path: %s", path)
}
log.Printf("extracting zipped file: %s -> %s", zipEntry.Name, normalizedDestination)

if stripPrefix != "" {
stripped := strings.Replace(zipFile.Name, stripPrefix, "", 1)
path = filepath.Join(destinationDir, stripped)
// log.Println("wat1", stripPrefix, path)
}
_, err = io.Copy(file, zipReadCloser)
if err != nil {
return err
}

if zipFile.FileInfo().IsDir() {
os.MkdirAll(path, os.ModePerm)
} else {
return nil
}

err := os.MkdirAll(filepath.Dir(path), os.ModePerm)
if err != nil {
return err
}
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, zipFile.Mode())
if err != nil {
return err
}

// log.Println("wat2", stripPrefix, path, f.Name())

defer func() {
if err := f.Close(); err != nil {
panic(err)
}
}()

// log.Printf("extracting zipped file: %s -> %s", zipFile.Name, f.Name())
_, err = io.Copy(f, zipReadCloser)
if err != nil {
return err
}
}
return nil
func (e *extractorImpl) Extract(zipFileName string, destinationDir string, stripPrefix string) error {

r, err := zip.OpenReader(zipFileName)
if err != nil {
return err
}
defer r.Close()

for _, f := range r.File {

// stripPrefix := getPrefixToStrip(f)
// if stripPrefix != "" {
// log.Printf("stripping prefix '%s' from %s\n", stripPrefix, f.Name)
// }
var normalizedFilePath string

if runtime.GOOS == "windows" {
// Convert to Windows path format
normalizedFilePath = strings.ReplaceAll(f.Name, "/", "\\")
} else {
// Convert to Unix path format
normalizedFilePath = strings.ReplaceAll(f.Name, "\\", "/")
}

normalizedFilePath, _ = strings.CutPrefix(normalizedFilePath, stripPrefix)

destination := path.Join(destinationDir, normalizedFilePath)

err := extractAndWriteFile(f, stripPrefix)
err := ExtractAndWriteFile(f, destination)
if err != nil {
return err
}
Expand Down

0 comments on commit c919f19

Please sign in to comment.