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 | |||
| 5 | 5 | require ( | |
| 6 | 6 | github.com/AlecAivazis/survey/v2 v2.3.7 | |
| 7 | 7 | github.com/Masterminds/semver/v3 v3.3.1 | |
| 8 | - | github.com/PuerkitoBio/goquery v1.9.2 | |
| 8 | + | github.com/PuerkitoBio/goquery v1.10.2 | |
| 9 | 9 | github.com/charmbracelet/bubbles v0.20.0 | |
| 10 | - | github.com/charmbracelet/lipgloss v0.13.0 | |
| 10 | + | github.com/charmbracelet/lipgloss v1.0.0 | |
| 11 | 11 | 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 | |
| 13 | 13 | github.com/docker/go-connections v0.5.0 | |
| 14 | - | github.com/fatih/color v1.17.0 | |
| 14 | + | github.com/fatih/color v1.18.0 | |
| 15 | 15 | github.com/gorilla/sessions v1.4.0 | |
| 16 | 16 | 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 | |
| 18 | 18 | github.com/labstack/echo/v4 v4.13.3 | |
| 19 | 19 | 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 | |
| 22 | 21 | github.com/starskey-io/starskey v0.1.8 | |
| 23 | 22 | gopkg.in/yaml.v3 v3.0.1 | |
| 24 | - | modernc.org/sqlite v1.32.0 | |
| 23 | + | modernc.org/sqlite v1.36.0 | |
| 25 | 24 | ) | |
| 26 | 25 | ||
| 27 | 26 | require ( | |
| 28 | 27 | 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 | |
| 31 | 30 | 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 | |
| 33 | 34 | ) | |
| 34 | 35 | ||
| 35 | 36 | require ( | |
| 36 | 37 | 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 | |
| 40 | 41 | github.com/containerd/log v0.1.0 // indirect | |
| 41 | 42 | github.com/creack/pty v1.1.18 // indirect | |
| 42 | 43 | github.com/distribution/reference v0.6.0 // indirect | |
| @@ -46,10 +47,8 @@ require ( | |||
| 46 | 47 | github.com/go-logfmt/logfmt v0.6.0 // indirect | |
| 47 | 48 | github.com/go-logr/logr v1.4.2 // indirect | |
| 48 | 49 | github.com/go-logr/stdr v1.2.2 // indirect | |
| 49 | - | github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect | |
| 50 | 50 | github.com/inconshreveable/mousetrap v1.1.0 // indirect | |
| 51 | 51 | github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect | |
| 52 | - | github.com/kr/pretty v0.3.1 // indirect | |
| 53 | 52 | github.com/lucasb-eyer/go-colorful v1.2.0 // indirect | |
| 54 | 53 | github.com/mattn/go-localereader v0.0.1 // indirect | |
| 55 | 54 | github.com/mattn/go-runewidth v0.0.16 // indirect | |
| @@ -57,32 +56,28 @@ require ( | |||
| 57 | 56 | github.com/moby/docker-image-spec v1.3.1 // indirect | |
| 58 | 57 | github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect | |
| 59 | 58 | 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 | |
| 61 | 60 | github.com/ncruces/go-strftime v0.1.9 // indirect | |
| 62 | 61 | github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect | |
| 63 | 62 | 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 | |
| 67 | 66 | 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 | |
| 72 | 70 | golang.org/x/sync v0.12.0 // indirect | |
| 73 | 71 | golang.org/x/term v0.30.0 // indirect | |
| 74 | 72 | 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 | |
| 81 | 76 | ) | |
| 82 | 77 | ||
| 83 | 78 | require ( | |
| 84 | 79 | 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 | |
| 86 | 81 | github.com/aymerick/douceur v0.2.0 // indirect | |
| 87 | 82 | github.com/docker/go-units v0.5.0 // indirect | |
| 88 | 83 | github.com/gogo/protobuf v1.3.2 // indirect | |
| @@ -91,22 +86,19 @@ require ( | |||
| 91 | 86 | github.com/gorilla/css v1.0.1 // indirect | |
| 92 | 87 | github.com/gorilla/securecookie v1.1.2 // indirect | |
| 93 | 88 | 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 | |
| 95 | 90 | github.com/mattn/go-isatty v0.0.20 // indirect | |
| 96 | 91 | github.com/moby/term v0.5.0 // indirect | |
| 97 | 92 | github.com/morikuni/aec v1.0.0 // indirect | |
| 98 | 93 | 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 | |
| 100 | 95 | github.com/pkg/errors v0.9.1 // indirect | |
| 101 | - | github.com/rogpeppe/go-internal v1.11.0 // indirect | |
| 102 | 96 | github.com/valyala/bytebufferpool v1.0.0 // indirect | |
| 103 | 97 | github.com/valyala/fasttemplate v1.2.2 // indirect | |
| 104 | 98 | 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 | |
| 106 | 100 | golang.org/x/sys v0.31.0 // indirect | |
| 107 | 101 | 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 | |
| 111 | 103 | gotest.tools/v3 v3.5.0 // indirect | |
| 112 | 104 | ) | |
| @@ -5,38 +5,39 @@ go 1.24.1 | |||||
| 5 | require ( | 5 | require ( | ||
| 6 | github.com/AlecAivazis/survey/v2 v2.3.7 | 6 | github.com/AlecAivazis/survey/v2 v2.3.7 | ||
| 7 | github.com/Masterminds/semver/v3 v3.3.1 | 7 | github.com/Masterminds/semver/v3 v3.3.1 | ||
| 8 | - | github.com/PuerkitoBio/goquery v1.9.2 | 8 | + | github.com/PuerkitoBio/goquery v1.10.2 |
| 9 | github.com/charmbracelet/bubbles v0.20.0 | 9 | github.com/charmbracelet/bubbles v0.20.0 | ||
| 10 | - | github.com/charmbracelet/lipgloss v0.13.0 | 10 | + | github.com/charmbracelet/lipgloss v1.0.0 |
| 11 | github.com/charmbracelet/log v0.4.0 | 11 | 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 |
| 13 | github.com/docker/go-connections v0.5.0 | 13 | github.com/docker/go-connections v0.5.0 | ||
| 14 | - | github.com/fatih/color v1.17.0 | 14 | + | github.com/fatih/color v1.18.0 |
| 15 | github.com/gorilla/sessions v1.4.0 | 15 | github.com/gorilla/sessions v1.4.0 | ||
| 16 | github.com/joho/godotenv v1.5.1 | 16 | 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 |
| 18 | github.com/labstack/echo/v4 v4.13.3 | 18 | github.com/labstack/echo/v4 v4.13.3 | ||
| 19 | github.com/microcosm-cc/bluemonday v1.0.27 | 19 | github.com/microcosm-cc/bluemonday v1.0.27 | ||
| 20 | - | github.com/pocketbase/pocketbase v0.22.19 | 20 | + | github.com/spf13/cobra v1.9.1 |
| 21 | - | github.com/spf13/cobra v1.8.1 | |||
| 22 | github.com/starskey-io/starskey v0.1.8 | 21 | github.com/starskey-io/starskey v0.1.8 | ||
| 23 | gopkg.in/yaml.v3 v3.0.1 | 22 | gopkg.in/yaml.v3 v3.0.1 | ||
| 24 | - | modernc.org/sqlite v1.32.0 | 23 | + | modernc.org/sqlite v1.36.0 |
| 25 | ) | 24 | ) | ||
| 26 | 25 | ||||
| 27 | require ( | 26 | require ( | ||
| 28 | github.com/cespare/xxhash/v2 v2.3.0 // indirect | 27 | github.com/cespare/xxhash/v2 v2.3.0 // indirect | ||
| 29 | - | github.com/klauspost/compress v1.16.7 // indirect | 28 | + | github.com/klauspost/compress v1.18.0 // indirect |
| 30 | - | github.com/klauspost/cpuid/v2 v2.0.9 // indirect | 29 | + | github.com/klauspost/cpuid/v2 v2.2.10 // indirect |
| 31 | github.com/zeebo/xxh3 v1.0.2 // indirect | 30 | 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 | |||
| 33 | ) | 34 | ) | ||
| 34 | 35 | ||||
| 35 | require ( | 36 | require ( | ||
| 36 | github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect | 37 | github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect | ||
| 37 | - | github.com/charmbracelet/bubbletea v1.1.0 // direct | 38 | + | github.com/charmbracelet/bubbletea v1.3.4 // direct |
| 38 | - | github.com/charmbracelet/x/ansi v0.2.3 // indirect | 39 | + | github.com/charmbracelet/x/ansi v0.8.0 // indirect |
| 39 | - | github.com/charmbracelet/x/term v0.2.0 // indirect | 40 | + | github.com/charmbracelet/x/term v0.2.1 // indirect |
| 40 | github.com/containerd/log v0.1.0 // indirect | 41 | github.com/containerd/log v0.1.0 // indirect | ||
| 41 | github.com/creack/pty v1.1.18 // indirect | 42 | github.com/creack/pty v1.1.18 // indirect | ||
| 42 | github.com/distribution/reference v0.6.0 // indirect | 43 | github.com/distribution/reference v0.6.0 // indirect | ||
| @@ -46,10 +47,8 @@ require ( | |||||
| 46 | github.com/go-logfmt/logfmt v0.6.0 // indirect | 47 | github.com/go-logfmt/logfmt v0.6.0 // indirect | ||
| 47 | github.com/go-logr/logr v1.4.2 // indirect | 48 | github.com/go-logr/logr v1.4.2 // indirect | ||
| 48 | github.com/go-logr/stdr v1.2.2 // indirect | 49 | 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 // indirect | 50 | github.com/inconshreveable/mousetrap v1.1.0 // indirect | ||
| 51 | github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect | 51 | 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 // indirect | 52 | github.com/lucasb-eyer/go-colorful v1.2.0 // indirect | ||
| 54 | github.com/mattn/go-localereader v0.0.1 // indirect | 53 | github.com/mattn/go-localereader v0.0.1 // indirect | ||
| 55 | github.com/mattn/go-runewidth v0.0.16 // indirect | 54 | github.com/mattn/go-runewidth v0.0.16 // indirect | ||
| @@ -57,32 +56,28 @@ require ( | |||||
| 57 | github.com/moby/docker-image-spec v1.3.1 // indirect | 56 | github.com/moby/docker-image-spec v1.3.1 // indirect | ||
| 58 | github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect | 57 | github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect | ||
| 59 | github.com/muesli/cancelreader v0.2.2 // indirect | 58 | 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 |
| 61 | github.com/ncruces/go-strftime v0.1.9 // indirect | 60 | github.com/ncruces/go-strftime v0.1.9 // indirect | ||
| 62 | github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect | 61 | github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect | ||
| 63 | github.com/rivo/uniseg v0.4.7 // indirect | 62 | github.com/rivo/uniseg v0.4.7 // indirect | ||
| 64 | - | github.com/spf13/pflag v1.0.5 // indirect | 63 | + | github.com/spf13/pflag v1.0.6 // indirect |
| 65 | - | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect | 64 | + | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect |
| 66 | - | go.opentelemetry.io/otel v1.29.0 // indirect | 65 | + | go.opentelemetry.io/otel v1.35.0 // indirect |
| 67 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 // indirect | 66 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 // indirect | ||
| 68 | - | go.opentelemetry.io/otel/metric v1.29.0 // indirect | 67 | + | go.opentelemetry.io/otel/metric v1.35.0 // indirect |
| 69 | - | go.opentelemetry.io/otel/sdk v1.21.0 // indirect | 68 | + | go.opentelemetry.io/otel/trace v1.35.0 // indirect |
| 70 | - | go.opentelemetry.io/otel/trace v1.29.0 // indirect | 69 | + | 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 // indirect | 70 | golang.org/x/sync v0.12.0 // indirect | ||
| 73 | golang.org/x/term v0.30.0 // indirect | 71 | golang.org/x/term v0.30.0 // indirect | ||
| 74 | google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect | 72 | google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect | ||
| 75 | - | modernc.org/gc/v3 v3.0.0-20240801135723-a856999a2e4a // indirect | 73 | + | modernc.org/libc v1.61.13 // indirect |
| 76 | - | modernc.org/libc v1.59.9 // indirect | 74 | + | modernc.org/mathutil v1.7.1 // indirect |
| 77 | - | modernc.org/mathutil v1.6.0 // indirect | 75 | + | 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 // indirect | 79 | 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 |
| 86 | github.com/aymerick/douceur v0.2.0 // indirect | 81 | github.com/aymerick/douceur v0.2.0 // indirect | ||
| 87 | github.com/docker/go-units v0.5.0 // indirect | 82 | github.com/docker/go-units v0.5.0 // indirect | ||
| 88 | github.com/gogo/protobuf v1.3.2 // indirect | 83 | github.com/gogo/protobuf v1.3.2 // indirect | ||
| @@ -91,22 +86,19 @@ require ( | |||||
| 91 | github.com/gorilla/css v1.0.1 // indirect | 86 | github.com/gorilla/css v1.0.1 // indirect | ||
| 92 | github.com/gorilla/securecookie v1.1.2 // indirect | 87 | github.com/gorilla/securecookie v1.1.2 // indirect | ||
| 93 | github.com/labstack/gommon v0.4.2 // indirect | 88 | 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 |
| 95 | github.com/mattn/go-isatty v0.0.20 // indirect | 90 | github.com/mattn/go-isatty v0.0.20 // indirect | ||
| 96 | github.com/moby/term v0.5.0 // indirect | 91 | github.com/moby/term v0.5.0 // indirect | ||
| 97 | github.com/morikuni/aec v1.0.0 // indirect | 92 | github.com/morikuni/aec v1.0.0 // indirect | ||
| 98 | github.com/opencontainers/go-digest v1.0.0 // indirect | 93 | 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 |
| 100 | github.com/pkg/errors v0.9.1 // indirect | 95 | 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 // indirect | 96 | github.com/valyala/bytebufferpool v1.0.0 // indirect | ||
| 103 | github.com/valyala/fasttemplate v1.2.2 // indirect | 97 | github.com/valyala/fasttemplate v1.2.2 // indirect | ||
| 104 | golang.org/x/crypto v0.36.0 | 98 | 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 |
| 106 | golang.org/x/sys v0.31.0 // indirect | 100 | golang.org/x/sys v0.31.0 // indirect | ||
| 107 | golang.org/x/text v0.23.0 // indirect | 101 | golang.org/x/text v0.23.0 // indirect | ||
| 108 | - | golang.org/x/time v0.8.0 // direct | 102 | + | 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 // indirect | 103 | 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 @@ | |||
| 4 | 4 | package cmd | |
| 5 | 5 | ||
| 6 | 6 | import ( | |
| 7 | + | "archive/zip" | |
| 7 | 8 | "context" | |
| 8 | 9 | "encoding/json" | |
| 9 | 10 | "errors" | |
| @@ -22,7 +23,6 @@ import ( | |||
| 22 | 23 | "github.com/bnema/gordon/internal/cli/handler" | |
| 23 | 24 | "github.com/bnema/gordon/pkg/docker" | |
| 24 | 25 | "github.com/fatih/color" | |
| 25 | - | "github.com/pocketbase/pocketbase/tools/archive" | |
| 26 | 26 | "github.com/spf13/cobra" | |
| 27 | 27 | ) | |
| 28 | 28 | ||
| @@ -166,7 +166,7 @@ func (p *plugin) update() error { | |||
| 166 | 166 | extractDir := filepath.Join(releaseDir, "extracted_"+asset.Name) | |
| 167 | 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 | 170 | return err | |
| 171 | 171 | } | |
| 172 | 172 | ||
| @@ -404,3 +404,70 @@ func checkWritePermission(path string) error { | |||
| 404 | 404 | func isRoot() bool { | |
| 405 | 405 | 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 | + | } | |
| @@ -4,6 +4,7 @@ | |||||
| 4 | package cmd | 4 | 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 err | 170 | 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() == 0 | 405 | 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 | + | } | |||