Skip to content

Commit

Permalink
安全的拼接路径
Browse files Browse the repository at this point in the history
  • Loading branch information
xmdhs committed Jan 30, 2024
1 parent e19462a commit 398bfaa
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 97 deletions.
19 changes: 15 additions & 4 deletions download/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"sync/atomic"

"github.com/avast/retry-go/v4"
"github.com/xmdhs/gomclauncher/internal"
"github.com/xmdhs/gomclauncher/lang"
"github.com/xmdhs/gomclauncher/launcher"
"golang.org/x/sync/errgroup"
Expand All @@ -33,9 +34,13 @@ func (l Libraries) Downassets(i int, c chan int) error {
g.Go(func() error {
ok := ver(l.path+`/assets/objects/`+v.Hash[:2]+`/`+v.Hash, v.Hash)
if !ok {
path, err := internal.SafePathJoin(l.path, `/assets/objects/`, v.Hash[:2], v.Hash)
if err != nil {
return err
}
d := downinfo{
url: `https://resources.download.minecraft.net/` + v.Hash[:2] + `/` + v.Hash,
path: l.path + `/assets/objects/` + v.Hash[:2] + `/` + v.Hash,
path: path,
Sha1: v.Hash,
randurls: l.randurls,
print: l.print,
Expand Down Expand Up @@ -94,7 +99,10 @@ func (l Libraries) Downlibrarie(i int, c chan int) error {
c <- len(l.librarie.Libraries) - int(n.Add(1))
continue
}
path := l.path + `/libraries/` + v.Downloads.Artifact.Path
path, err := internal.SafePathJoin(l.path, `/libraries/`, v.Downloads.Artifact.Path)
if err != nil {
return fmt.Errorf("Downlibrarie: %w", err)
}
if v.Downloads.Artifact.URL == "" {
c <- len(l.librarie.Libraries) - int(n.Add(1))
continue
Expand Down Expand Up @@ -128,13 +136,16 @@ func (l Libraries) Downlibrarie(i int, c chan int) error {
var FileDownLoadFail = errors.New("file download fail")

func (l Libraries) Downjar(version string) error {
path := l.path + `/versions/` + version + "/" + version + ".jar"
path, err := internal.SafePathJoin(l.path, `/versions/`, version, version+".jar")
if err != nil {
return fmt.Errorf("Downjar: %w %w", err, FileDownLoadFail)
}
if ver(path, l.librarie.Downloads.Client.Sha1) {
return nil
}
_, t := l.auto()

err := retry.Do(func() error {
err = retry.Do(func() error {
u := source(l.librarie.Downloads.Client.URL, t)
err := get(l.cxt, u, path)
if err != nil {
Expand Down
11 changes: 9 additions & 2 deletions download/libraries.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ func Newlibraries(cxt context.Context, b []byte, typee string, print func(string
return Libraries{}, fmt.Errorf("Newlibraries: %w", err)
}
if mod.InheritsFrom != "" {
b, err := os.ReadFile(apath + `/versions/` + mod.InheritsFrom + "/" + mod.InheritsFrom + ".json")
npath, err := internal.SafePathJoin(apath, `/versions/`, mod.InheritsFrom, mod.InheritsFrom+".json")
if err != nil {
return Libraries{}, fmt.Errorf("Newlibraries: %w", err)
}
b, err := os.ReadFile(npath)
if err != nil {
return Libraries{}, fmt.Errorf("Newlibraries: %w", err)
}
Expand All @@ -60,7 +64,10 @@ func Newlibraries(cxt context.Context, b []byte, typee string, print func(string
}
url = l.AssetIndex.URL
id = l.AssetIndex.ID
path := apath + "/assets/indexes/" + id + ".json"
path, err := internal.SafePathJoin(apath, "/assets/indexes/", id+".json")
if err != nil {
return Libraries{}, fmt.Errorf("Newlibraries: %w", err)
}
if !ver(path, l.AssetIndex.Sha1) {
err := assetsjson(cxt, r, url, path, typee, l.AssetIndex.Sha1, print)
if err != nil {
Expand Down
8 changes: 6 additions & 2 deletions download/unzip.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"path/filepath"
"strings"

"github.com/xmdhs/gomclauncher/internal"
"github.com/xmdhs/gomclauncher/launcher"
"golang.org/x/sync/errgroup"
)
Expand All @@ -24,7 +25,10 @@ func (l Libraries) Unzip(i int) error {
if url == "" {
continue
}
path = l.path + `/libraries/` + path
path, err := internal.SafePathJoin(l.path, `/libraries/`, path)
if err != nil {
return fmt.Errorf("Unzip: %w", err)
}
allow := launcher.Ifallow(v)
if allow {
natives = append(natives, path)
Expand All @@ -42,7 +46,7 @@ func (l Libraries) Unzip(i int) error {
}
err := g.Wait()
if err != nil {
return fmt.Errorf("Downassets: %w", err)
return fmt.Errorf("Unzip: %w", err)
}
return l.unzipnative(natives)
}
Expand Down
8 changes: 6 additions & 2 deletions download/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strings"

"github.com/avast/retry-go/v4"
"github.com/xmdhs/gomclauncher/internal"
"github.com/xmdhs/gomclauncher/lang"
)

Expand Down Expand Up @@ -73,12 +74,15 @@ func (v version) Downjson(cxt context.Context, version, apath string, print func
for _, vv := range v.Versions {
if vv.ID == version {
s := strings.Split(vv.URL, "/")
path := apath + `/versions/` + vv.ID + `/` + vv.ID + `.json`
path, err := internal.SafePathJoin(apath, `/versions/`, vv.ID, vv.ID+".json")
if err != nil {
return fmt.Errorf("Downjson: %w", err)
}
if ver(path, s[len(s)-2]) {
return nil
}

err := retry.Do(func() error {
err = retry.Do(func() error {
url := source(vv.URL, f)
err := get(cxt, url, path)
if err != nil {
Expand Down
8 changes: 7 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,14 @@ require (
github.com/avast/retry-go/v4 v4.5.1
github.com/cli/browser v1.3.0
github.com/cli/oauth v1.0.1
github.com/stretchr/testify v1.8.4
golang.org/x/sync v0.6.0
golang.org/x/text v0.14.0
)

require golang.org/x/sys v0.16.0 // indirect
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/sys v0.16.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
21 changes: 7 additions & 14 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@ github.com/Xuanwo/go-locale v1.1.0/go.mod h1:UKrHoZB3FPIk9wIG2/tVSobnHgNnceGSH3Y
github.com/avast/retry-go/v4 v4.5.1 h1:AxIx0HGi4VZ3I02jr78j5lZ3M6x1E0Ivxa6b0pUUh7o=
github.com/avast/retry-go/v4 v4.5.1/go.mod h1:/sipNsvNB3RRuT5iNcb6h73nw3IBmXJ/H3XrCQYSOpc=
github.com/cli/browser v1.0.0/go.mod h1:IEWkHYbLjkhtjwwWlwTHW2lGxeS5gezEQBMLTwDHf5Q=
github.com/cli/browser v1.2.0 h1:yvU7e9qf97kZqGFX6n2zJPHsmSObY9ske+iCvKelvXg=
github.com/cli/browser v1.2.0/go.mod h1:xFFnXLVcAyW9ni0cuo6NnrbCP75JxJ0RO7VtCBiH/oI=
github.com/cli/browser v1.3.0 h1:LejqCrpWr+1pRqmEPDGnTZOjsMe7sehifLynZJuqJpo=
github.com/cli/browser v1.3.0/go.mod h1:HH8s+fOAxjhQoBUAsKuPCbqUuxZDhQ2/aD+SzsEfBTk=
github.com/cli/oauth v1.0.1 h1:pXnTFl/qUegXHK531Dv0LNjW4mLx626eS42gnzfXJPA=
github.com/cli/oauth v1.0.1/go.mod h1:qd/FX8ZBD6n1sVNQO3aIdRxeu5LGw9WhKnYhIIoC2A4=
github.com/cli/safeexec v1.0.0/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
Expand All @@ -25,31 +24,25 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1
github.com/smartystreets/goconvey v1.6.7 h1:I6tZjLXD2Q1kjvNbIzB1wvQBsXmKXiVrhpRE8ZjP5jY=
github.com/smartystreets/goconvey v1.6.7/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211023085530-d6a326fbbf70/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
17 changes: 17 additions & 0 deletions internal/unit.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ package internal

import (
"context"
"errors"
"fmt"
"net/http"
"path/filepath"
"runtime"
"strings"
"time"
)

Expand Down Expand Up @@ -43,3 +46,17 @@ func HttpGet(cxt context.Context, aurl string, t *http.Transport, header http.He
}
return reps, timer, nil
}

var ErrPathNotInBase = errors.New("path not in base")

func SafePathJoin(base string, path ...string) (string, error) {
p := filepath.Join(append([]string{base}, path...)...)
a, err := filepath.Rel(base, p)
if err != nil {
return "", fmt.Errorf("SafePathJoin: %w", err)
}
if strings.HasPrefix(a, ".") {
return "", ErrPathNotInBase
}
return p, nil
}
20 changes: 20 additions & 0 deletions internal/unit_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package internal

import (
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
)

func TestSafePathJoin(t *testing.T) {
p, err := SafePathJoin(".minecraft", "aaa")
assert.Nil(t, err)
assert.Equal(t, p, ".minecraft"+string(filepath.Separator)+"aaa")

_, err = SafePathJoin(".minecraft", "../aaa")
assert.ErrorIs(t, err, ErrPathNotInBase)

_, err = SafePathJoin(".minecraft", "aaa/../../a")
assert.ErrorIs(t, err, ErrPathNotInBase)
}
Loading

0 comments on commit 398bfaa

Please sign in to comment.