detached 5a72af7

feat: Update Go dependencies and replace external archive extraction

- Update Go module dependencies to latest versions
- Remove dependency on PocketBase archive extraction
- Implement custom `extractZip` function to replace external archive extraction
- Enhance zip file extraction with improved security and error handling
- Add path traversal protection during zip extraction
- Preserve file permissions when extracting zip files
commit
5a72af758b1090035ae5832e5df80376dc0a3e19
author
bamen · · 2025-03-09 18:00 UTC
committer
bamen · · 2025-03-09 18:11 UTC
parent
2776772
signature
unsigned
3 files · +224 -141
M go.mod +30 -38
@@ -5,38 +5,39 @@ go 1.24.1
55 require (
66 github.com/AlecAivazis/survey/v2 v2.3.7
77 github.com/Masterminds/semver/v3 v3.3.1
8- github.com/PuerkitoBio/goquery v1.9.2
8+ github.com/PuerkitoBio/goquery v1.10.2
99 github.com/charmbracelet/bubbles v0.20.0
10- github.com/charmbracelet/lipgloss v0.13.0
10+ github.com/charmbracelet/lipgloss v1.0.0
1111 github.com/charmbracelet/log v0.4.0
12- github.com/docker/docker v27.1.2+incompatible
12+ github.com/docker/docker v28.0.1+incompatible
1313 github.com/docker/go-connections v0.5.0
14- github.com/fatih/color v1.17.0
14+ github.com/fatih/color v1.18.0
1515 github.com/gorilla/sessions v1.4.0
1616 github.com/joho/godotenv v1.5.1
17- github.com/labstack/echo-contrib v0.17.1
17+ github.com/labstack/echo-contrib v0.17.2
1818 github.com/labstack/echo/v4 v4.13.3
1919 github.com/microcosm-cc/bluemonday v1.0.27
20- github.com/pocketbase/pocketbase v0.22.19
21- github.com/spf13/cobra v1.8.1
20+ github.com/spf13/cobra v1.9.1
2221 github.com/starskey-io/starskey v0.1.8
2322 gopkg.in/yaml.v3 v3.0.1
24- modernc.org/sqlite v1.32.0
23+ modernc.org/sqlite v1.36.0
2524 )
2625
2726 require (
2827 github.com/cespare/xxhash/v2 v2.3.0 // indirect
29- github.com/klauspost/compress v1.16.7 // indirect
30- github.com/klauspost/cpuid/v2 v2.0.9 // indirect
28+ github.com/klauspost/compress v1.18.0 // indirect
29+ github.com/klauspost/cpuid/v2 v2.2.10 // indirect
3130 github.com/zeebo/xxh3 v1.0.2 // indirect
32- go.mongodb.org/mongo-driver v1.17.2 // indirect
31+ go.mongodb.org/mongo-driver v1.17.3 // indirect
32+ go.opentelemetry.io/auto/sdk v1.1.0 // indirect
33+ google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e // indirect
3334 )
3435
3536 require (
3637 github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
37- github.com/charmbracelet/bubbletea v1.1.0 // direct
38- github.com/charmbracelet/x/ansi v0.2.3 // indirect
39- github.com/charmbracelet/x/term v0.2.0 // indirect
38+ github.com/charmbracelet/bubbletea v1.3.4 // direct
39+ github.com/charmbracelet/x/ansi v0.8.0 // indirect
40+ github.com/charmbracelet/x/term v0.2.1 // indirect
4041 github.com/containerd/log v0.1.0 // indirect
4142 github.com/creack/pty v1.1.18 // indirect
4243 github.com/distribution/reference v0.6.0 // indirect
@@ -46,10 +47,8 @@ require (
4647 github.com/go-logfmt/logfmt v0.6.0 // indirect
4748 github.com/go-logr/logr v1.4.2 // indirect
4849 github.com/go-logr/stdr v1.2.2 // indirect
49- github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
5050 github.com/inconshreveable/mousetrap v1.1.0 // indirect
5151 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
52- github.com/kr/pretty v0.3.1 // indirect
5352 github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
5453 github.com/mattn/go-localereader v0.0.1 // indirect
5554 github.com/mattn/go-runewidth v0.0.16 // indirect
@@ -57,32 +56,28 @@ require (
5756 github.com/moby/docker-image-spec v1.3.1 // indirect
5857 github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
5958 github.com/muesli/cancelreader v0.2.2 // indirect
60- github.com/muesli/termenv v0.15.2 // indirect
59+ github.com/muesli/termenv v0.16.0 // indirect
6160 github.com/ncruces/go-strftime v0.1.9 // indirect
6261 github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
6362 github.com/rivo/uniseg v0.4.7 // indirect
64- github.com/spf13/pflag v1.0.5 // indirect
65- go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
66- go.opentelemetry.io/otel v1.29.0 // indirect
63+ github.com/spf13/pflag v1.0.6 // indirect
64+ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
65+ go.opentelemetry.io/otel v1.35.0 // indirect
6766 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 // indirect
68- go.opentelemetry.io/otel/metric v1.29.0 // indirect
69- go.opentelemetry.io/otel/sdk v1.21.0 // indirect
70- go.opentelemetry.io/otel/trace v1.29.0 // indirect
71- golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 // direct
67+ go.opentelemetry.io/otel/metric v1.35.0 // indirect
68+ go.opentelemetry.io/otel/trace v1.35.0 // indirect
69+ golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // direct
7270 golang.org/x/sync v0.12.0 // indirect
7371 golang.org/x/term v0.30.0 // indirect
7472 google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect
75- modernc.org/gc/v3 v3.0.0-20240801135723-a856999a2e4a // indirect
76- modernc.org/libc v1.59.9 // indirect
77- modernc.org/mathutil v1.6.0 // indirect
78- modernc.org/memory v1.8.0 // indirect
79- modernc.org/strutil v1.2.0 // indirect
80- modernc.org/token v1.1.0 // indirect
73+ modernc.org/libc v1.61.13 // indirect
74+ modernc.org/mathutil v1.7.1 // indirect
75+ modernc.org/memory v1.8.2 // indirect
8176 )
8277
8378 require (
8479 github.com/Microsoft/go-winio v0.6.2 // indirect
85- github.com/andybalholm/cascadia v1.3.2 // indirect
80+ github.com/andybalholm/cascadia v1.3.3 // indirect
8681 github.com/aymerick/douceur v0.2.0 // indirect
8782 github.com/docker/go-units v0.5.0 // indirect
8883 github.com/gogo/protobuf v1.3.2 // indirect
@@ -91,22 +86,19 @@ require (
9186 github.com/gorilla/css v1.0.1 // indirect
9287 github.com/gorilla/securecookie v1.1.2 // indirect
9388 github.com/labstack/gommon v0.4.2 // indirect
94- github.com/mattn/go-colorable v0.1.13 // indirect
89+ github.com/mattn/go-colorable v0.1.14 // indirect
9590 github.com/mattn/go-isatty v0.0.20 // indirect
9691 github.com/moby/term v0.5.0 // indirect
9792 github.com/morikuni/aec v1.0.0 // indirect
9893 github.com/opencontainers/go-digest v1.0.0 // indirect
99- github.com/opencontainers/image-spec v1.1.0 // indirect
94+ github.com/opencontainers/image-spec v1.1.1 // indirect
10095 github.com/pkg/errors v0.9.1 // indirect
101- github.com/rogpeppe/go-internal v1.11.0 // indirect
10296 github.com/valyala/bytebufferpool v1.0.0 // indirect
10397 github.com/valyala/fasttemplate v1.2.2 // indirect
10498 golang.org/x/crypto v0.36.0
105- golang.org/x/net v0.33.0 // indirect
99+ golang.org/x/net v0.37.0 // indirect
106100 golang.org/x/sys v0.31.0 // indirect
107101 golang.org/x/text v0.23.0 // indirect
108- golang.org/x/time v0.8.0 // direct
109- golang.org/x/tools v0.24.0 // indirect
110- gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
102+ golang.org/x/time v0.11.0 // direct
111103 gotest.tools/v3 v3.5.0 // indirect
112104 )
@@ -5,38 +5,39 @@ go 1.24.1
5 require (5 require (
6 github.com/AlecAivazis/survey/v2 v2.3.76 github.com/AlecAivazis/survey/v2 v2.3.7
7 github.com/Masterminds/semver/v3 v3.3.17 github.com/Masterminds/semver/v3 v3.3.1
8- github.com/PuerkitoBio/goquery v1.9.28+ github.com/PuerkitoBio/goquery v1.10.2
9 github.com/charmbracelet/bubbles v0.20.09 github.com/charmbracelet/bubbles v0.20.0
10- github.com/charmbracelet/lipgloss v0.13.010+ github.com/charmbracelet/lipgloss v1.0.0
11 github.com/charmbracelet/log v0.4.011 github.com/charmbracelet/log v0.4.0
12- github.com/docker/docker v27.1.2+incompatible12+ github.com/docker/docker v28.0.1+incompatible
13 github.com/docker/go-connections v0.5.013 github.com/docker/go-connections v0.5.0
14- github.com/fatih/color v1.17.014+ github.com/fatih/color v1.18.0
15 github.com/gorilla/sessions v1.4.015 github.com/gorilla/sessions v1.4.0
16 github.com/joho/godotenv v1.5.116 github.com/joho/godotenv v1.5.1
17- github.com/labstack/echo-contrib v0.17.117+ github.com/labstack/echo-contrib v0.17.2
18 github.com/labstack/echo/v4 v4.13.318 github.com/labstack/echo/v4 v4.13.3
19 github.com/microcosm-cc/bluemonday v1.0.2719 github.com/microcosm-cc/bluemonday v1.0.27
20- github.com/pocketbase/pocketbase v0.22.1920+ github.com/spf13/cobra v1.9.1
21- github.com/spf13/cobra v1.8.1
22 github.com/starskey-io/starskey v0.1.821 github.com/starskey-io/starskey v0.1.8
23 gopkg.in/yaml.v3 v3.0.122 gopkg.in/yaml.v3 v3.0.1
24- modernc.org/sqlite v1.32.023+ modernc.org/sqlite v1.36.0
25 )24 )
26 25
27 require (26 require (
28 github.com/cespare/xxhash/v2 v2.3.0 // indirect27 github.com/cespare/xxhash/v2 v2.3.0 // indirect
29- github.com/klauspost/compress v1.16.7 // indirect28+ github.com/klauspost/compress v1.18.0 // indirect
30- github.com/klauspost/cpuid/v2 v2.0.9 // indirect29+ github.com/klauspost/cpuid/v2 v2.2.10 // indirect
31 github.com/zeebo/xxh3 v1.0.2 // indirect30 github.com/zeebo/xxh3 v1.0.2 // indirect
32- go.mongodb.org/mongo-driver v1.17.2 // indirect31+ go.mongodb.org/mongo-driver v1.17.3 // indirect
32+ go.opentelemetry.io/auto/sdk v1.1.0 // indirect
33+ google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e // indirect
33 )34 )
34 35
35 require (36 require (
36 github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect37 github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
37- github.com/charmbracelet/bubbletea v1.1.0 // direct38+ github.com/charmbracelet/bubbletea v1.3.4 // direct
38- github.com/charmbracelet/x/ansi v0.2.3 // indirect39+ github.com/charmbracelet/x/ansi v0.8.0 // indirect
39- github.com/charmbracelet/x/term v0.2.0 // indirect40+ github.com/charmbracelet/x/term v0.2.1 // indirect
40 github.com/containerd/log v0.1.0 // indirect41 github.com/containerd/log v0.1.0 // indirect
41 github.com/creack/pty v1.1.18 // indirect42 github.com/creack/pty v1.1.18 // indirect
42 github.com/distribution/reference v0.6.0 // indirect43 github.com/distribution/reference v0.6.0 // indirect
@@ -46,10 +47,8 @@ require (
46 github.com/go-logfmt/logfmt v0.6.0 // indirect47 github.com/go-logfmt/logfmt v0.6.0 // indirect
47 github.com/go-logr/logr v1.4.2 // indirect48 github.com/go-logr/logr v1.4.2 // indirect
48 github.com/go-logr/stdr v1.2.2 // indirect49 github.com/go-logr/stdr v1.2.2 // indirect
49- github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
50 github.com/inconshreveable/mousetrap v1.1.0 // indirect50 github.com/inconshreveable/mousetrap v1.1.0 // indirect
51 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect51 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
52- github.com/kr/pretty v0.3.1 // indirect
53 github.com/lucasb-eyer/go-colorful v1.2.0 // indirect52 github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
54 github.com/mattn/go-localereader v0.0.1 // indirect53 github.com/mattn/go-localereader v0.0.1 // indirect
55 github.com/mattn/go-runewidth v0.0.16 // indirect54 github.com/mattn/go-runewidth v0.0.16 // indirect
@@ -57,32 +56,28 @@ require (
57 github.com/moby/docker-image-spec v1.3.1 // indirect56 github.com/moby/docker-image-spec v1.3.1 // indirect
58 github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect57 github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
59 github.com/muesli/cancelreader v0.2.2 // indirect58 github.com/muesli/cancelreader v0.2.2 // indirect
60- github.com/muesli/termenv v0.15.2 // indirect59+ github.com/muesli/termenv v0.16.0 // indirect
61 github.com/ncruces/go-strftime v0.1.9 // indirect60 github.com/ncruces/go-strftime v0.1.9 // indirect
62 github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect61 github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
63 github.com/rivo/uniseg v0.4.7 // indirect62 github.com/rivo/uniseg v0.4.7 // indirect
64- github.com/spf13/pflag v1.0.5 // indirect63+ github.com/spf13/pflag v1.0.6 // indirect
65- go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect64+ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
66- go.opentelemetry.io/otel v1.29.0 // indirect65+ go.opentelemetry.io/otel v1.35.0 // indirect
67 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 // indirect66 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 // indirect
68- go.opentelemetry.io/otel/metric v1.29.0 // indirect67+ go.opentelemetry.io/otel/metric v1.35.0 // indirect
69- go.opentelemetry.io/otel/sdk v1.21.0 // indirect68+ go.opentelemetry.io/otel/trace v1.35.0 // indirect
70- go.opentelemetry.io/otel/trace v1.29.0 // indirect69+ golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // direct
71- golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 // direct
72 golang.org/x/sync v0.12.0 // indirect70 golang.org/x/sync v0.12.0 // indirect
73 golang.org/x/term v0.30.0 // indirect71 golang.org/x/term v0.30.0 // indirect
74 google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect72 google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect
75- modernc.org/gc/v3 v3.0.0-20240801135723-a856999a2e4a // indirect73+ modernc.org/libc v1.61.13 // indirect
76- modernc.org/libc v1.59.9 // indirect74+ modernc.org/mathutil v1.7.1 // indirect
77- modernc.org/mathutil v1.6.0 // indirect75+ modernc.org/memory v1.8.2 // indirect
78- modernc.org/memory v1.8.0 // indirect
79- modernc.org/strutil v1.2.0 // indirect
80- modernc.org/token v1.1.0 // indirect
81 )76 )
82 77
83 require (78 require (
84 github.com/Microsoft/go-winio v0.6.2 // indirect79 github.com/Microsoft/go-winio v0.6.2 // indirect
85- github.com/andybalholm/cascadia v1.3.2 // indirect80+ github.com/andybalholm/cascadia v1.3.3 // indirect
86 github.com/aymerick/douceur v0.2.0 // indirect81 github.com/aymerick/douceur v0.2.0 // indirect
87 github.com/docker/go-units v0.5.0 // indirect82 github.com/docker/go-units v0.5.0 // indirect
88 github.com/gogo/protobuf v1.3.2 // indirect83 github.com/gogo/protobuf v1.3.2 // indirect
@@ -91,22 +86,19 @@ require (
91 github.com/gorilla/css v1.0.1 // indirect86 github.com/gorilla/css v1.0.1 // indirect
92 github.com/gorilla/securecookie v1.1.2 // indirect87 github.com/gorilla/securecookie v1.1.2 // indirect
93 github.com/labstack/gommon v0.4.2 // indirect88 github.com/labstack/gommon v0.4.2 // indirect
94- github.com/mattn/go-colorable v0.1.13 // indirect89+ github.com/mattn/go-colorable v0.1.14 // indirect
95 github.com/mattn/go-isatty v0.0.20 // indirect90 github.com/mattn/go-isatty v0.0.20 // indirect
96 github.com/moby/term v0.5.0 // indirect91 github.com/moby/term v0.5.0 // indirect
97 github.com/morikuni/aec v1.0.0 // indirect92 github.com/morikuni/aec v1.0.0 // indirect
98 github.com/opencontainers/go-digest v1.0.0 // indirect93 github.com/opencontainers/go-digest v1.0.0 // indirect
99- github.com/opencontainers/image-spec v1.1.0 // indirect94+ github.com/opencontainers/image-spec v1.1.1 // indirect
100 github.com/pkg/errors v0.9.1 // indirect95 github.com/pkg/errors v0.9.1 // indirect
101- github.com/rogpeppe/go-internal v1.11.0 // indirect
102 github.com/valyala/bytebufferpool v1.0.0 // indirect96 github.com/valyala/bytebufferpool v1.0.0 // indirect
103 github.com/valyala/fasttemplate v1.2.2 // indirect97 github.com/valyala/fasttemplate v1.2.2 // indirect
104 golang.org/x/crypto v0.36.098 golang.org/x/crypto v0.36.0
105- golang.org/x/net v0.33.0 // indirect99+ golang.org/x/net v0.37.0 // indirect
106 golang.org/x/sys v0.31.0 // indirect100 golang.org/x/sys v0.31.0 // indirect
107 golang.org/x/text v0.23.0 // indirect101 golang.org/x/text v0.23.0 // indirect
108- golang.org/x/time v0.8.0 // direct102+ golang.org/x/time v0.11.0 // direct
109- golang.org/x/tools v0.24.0 // indirect
110- gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
111 gotest.tools/v3 v3.5.0 // indirect103 gotest.tools/v3 v3.5.0 // indirect
112 )104 )
M go.sum +125 -101 generated file: collapsed
M internal/cli/cmd/update.go +69 -2
@@ -4,6 +4,7 @@
44 package cmd
55
66 import (
7+ "archive/zip"
78 "context"
89 "encoding/json"
910 "errors"
@@ -22,7 +23,6 @@ import (
2223 "github.com/bnema/gordon/internal/cli/handler"
2324 "github.com/bnema/gordon/pkg/docker"
2425 "github.com/fatih/color"
25- "github.com/pocketbase/pocketbase/tools/archive"
2626 "github.com/spf13/cobra"
2727 )
2828
@@ -166,7 +166,7 @@ func (p *plugin) update() error {
166166 extractDir := filepath.Join(releaseDir, "extracted_"+asset.Name)
167167 defer os.RemoveAll(extractDir)
168168
169- if err := archive.Extract(assetZip, extractDir); err != nil {
169+ if err := extractZip(assetZip, extractDir); err != nil {
170170 return err
171171 }
172172
@@ -404,3 +404,70 @@ func checkWritePermission(path string) error {
404404 func isRoot() bool {
405405 return os.Geteuid() == 0
406406 }
407+
408+// extractZip extracts a zip file to a destination directory
409+func extractZip(zipPath, destPath string) error {
410+ // Open the zip file
411+ reader, err := zip.OpenReader(zipPath)
412+ if err != nil {
413+ return fmt.Errorf("failed to open zip file: %w", err)
414+ }
415+ defer reader.Close()
416+
417+ // Create destination directory if it doesn't exist
418+ if err := os.MkdirAll(destPath, os.ModePerm); err != nil {
419+ return fmt.Errorf("failed to create destination directory: %w", err)
420+ }
421+
422+ // Extract each file
423+ for _, file := range reader.File {
424+ // Construct the full path for the file
425+ path := filepath.Join(destPath, file.Name)
426+
427+ // Check for path traversal vulnerabilities
428+ if !strings.HasPrefix(path, filepath.Clean(destPath)+string(os.PathSeparator)) {
429+ return fmt.Errorf("illegal file path in zip: %s", file.Name)
430+ }
431+
432+ // Create directory for file
433+ if file.FileInfo().IsDir() {
434+ if err := os.MkdirAll(path, os.ModePerm); err != nil {
435+ return fmt.Errorf("failed to create directory: %w", err)
436+ }
437+ continue
438+ }
439+
440+ // Create parent directory if it doesn't exist
441+ if err := os.MkdirAll(filepath.Dir(path), os.ModePerm); err != nil {
442+ return fmt.Errorf("failed to create directory structure: %w", err)
443+ }
444+
445+ // Create file
446+ destFile, err := os.Create(path)
447+ if err != nil {
448+ return fmt.Errorf("failed to create file: %w", err)
449+ }
450+
451+ // Open the file in the zip
452+ srcFile, err := file.Open()
453+ if err != nil {
454+ destFile.Close()
455+ return fmt.Errorf("failed to open file in zip: %w", err)
456+ }
457+
458+ // Copy the contents
459+ _, err = io.Copy(destFile, srcFile)
460+ srcFile.Close()
461+ destFile.Close()
462+ if err != nil {
463+ return fmt.Errorf("failed to extract file: %w", err)
464+ }
465+
466+ // Preserve file permissions
467+ if err := os.Chmod(path, file.Mode()); err != nil {
468+ return fmt.Errorf("failed to set file permissions: %w", err)
469+ }
470+ }
471+
472+ return nil
473+}
@@ -4,6 +4,7 @@
4 package cmd4 package cmd
5 5
6 import (6 import (
7+ "archive/zip"
7 "context"8 "context"
8 "encoding/json"9 "encoding/json"
9 "errors"10 "errors"
@@ -22,7 +23,6 @@ import (
22 "github.com/bnema/gordon/internal/cli/handler"23 "github.com/bnema/gordon/internal/cli/handler"
23 "github.com/bnema/gordon/pkg/docker"24 "github.com/bnema/gordon/pkg/docker"
24 "github.com/fatih/color"25 "github.com/fatih/color"
25- "github.com/pocketbase/pocketbase/tools/archive"
26 "github.com/spf13/cobra"26 "github.com/spf13/cobra"
27 )27 )
28 28
@@ -166,7 +166,7 @@ func (p *plugin) update() error {
166 extractDir := filepath.Join(releaseDir, "extracted_"+asset.Name)166 extractDir := filepath.Join(releaseDir, "extracted_"+asset.Name)
167 defer os.RemoveAll(extractDir)167 defer os.RemoveAll(extractDir)
168 168
169- if err := archive.Extract(assetZip, extractDir); err != nil {169+ if err := extractZip(assetZip, extractDir); err != nil {
170 return err170 return err
171 }171 }
172 172
@@ -404,3 +404,70 @@ func checkWritePermission(path string) error {
404 func isRoot() bool {404 func isRoot() bool {
405 return os.Geteuid() == 0405 return os.Geteuid() == 0
406 }406 }
407+
408+// extractZip extracts a zip file to a destination directory
409+func extractZip(zipPath, destPath string) error {
410+ // Open the zip file
411+ reader, err := zip.OpenReader(zipPath)
412+ if err != nil {
413+ return fmt.Errorf("failed to open zip file: %w", err)
414+ }
415+ defer reader.Close()
416+
417+ // Create destination directory if it doesn't exist
418+ if err := os.MkdirAll(destPath, os.ModePerm); err != nil {
419+ return fmt.Errorf("failed to create destination directory: %w", err)
420+ }
421+
422+ // Extract each file
423+ for _, file := range reader.File {
424+ // Construct the full path for the file
425+ path := filepath.Join(destPath, file.Name)
426+
427+ // Check for path traversal vulnerabilities
428+ if !strings.HasPrefix(path, filepath.Clean(destPath)+string(os.PathSeparator)) {
429+ return fmt.Errorf("illegal file path in zip: %s", file.Name)
430+ }
431+
432+ // Create directory for file
433+ if file.FileInfo().IsDir() {
434+ if err := os.MkdirAll(path, os.ModePerm); err != nil {
435+ return fmt.Errorf("failed to create directory: %w", err)
436+ }
437+ continue
438+ }
439+
440+ // Create parent directory if it doesn't exist
441+ if err := os.MkdirAll(filepath.Dir(path), os.ModePerm); err != nil {
442+ return fmt.Errorf("failed to create directory structure: %w", err)
443+ }
444+
445+ // Create file
446+ destFile, err := os.Create(path)
447+ if err != nil {
448+ return fmt.Errorf("failed to create file: %w", err)
449+ }
450+
451+ // Open the file in the zip
452+ srcFile, err := file.Open()
453+ if err != nil {
454+ destFile.Close()
455+ return fmt.Errorf("failed to open file in zip: %w", err)
456+ }
457+
458+ // Copy the contents
459+ _, err = io.Copy(destFile, srcFile)
460+ srcFile.Close()
461+ destFile.Close()
462+ if err != nil {
463+ return fmt.Errorf("failed to extract file: %w", err)
464+ }
465+
466+ // Preserve file permissions
467+ if err := os.Chmod(path, file.Mode()); err != nil {
468+ return fmt.Errorf("failed to set file permissions: %w", err)
469+ }
470+ }
471+
472+ return nil
473+}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close