@@ -19,11 +19,13 @@ import (
19
19
"archive/zip"
20
20
"bytes"
21
21
"errors"
22
+ "fmt"
22
23
"io"
23
24
"os"
24
25
"os/exec"
25
26
"path"
26
27
"path/filepath"
28
+ "strings"
27
29
)
28
30
29
31
// SaveFileonTempDir creates a temp directory and saves the file data as the
@@ -32,15 +34,21 @@ import (
32
34
// Returns an error if the filename doesn't form a valid path.
33
35
//
34
36
// Note that path could be defined and still there could be an error.
35
- func SaveFileonTempDir (filename string , data io.Reader ) (path string , err error ) {
36
- // Create Temp Directory
37
+ func SaveFileonTempDir (filename string , data io.Reader ) (string , error ) {
37
38
tmpdir , err := os .MkdirTemp ("" , "arduino-create-agent" )
38
39
if err != nil {
39
40
return "" , errors .New ("Could not create temp directory to store downloaded file. Do you have permissions?" )
40
41
}
42
+ return saveFileonTempDir (tmpdir , filename , data )
43
+ }
41
44
45
+ func saveFileonTempDir (tmpDir , filename string , data io.Reader ) (string , error ) {
46
+ path , err := SafeJoin (tmpDir , filename )
47
+ if err != nil {
48
+ return "" , err
49
+ }
42
50
// Determine filename
43
- filename , err = filepath .Abs (tmpdir + "/" + filename )
51
+ filename , err = filepath .Abs (path )
44
52
if err != nil {
45
53
return "" , err
46
54
}
@@ -141,3 +149,16 @@ func Unzip(zippath string, destination string) (err error) {
141
149
}
142
150
return
143
151
}
152
+
153
+ // SafeJoin performs a filepath.Join of 'parent' and 'subdir' but returns an error
154
+ // if the resulting path points outside of 'parent'.
155
+ func SafeJoin (parent , subdir string ) (string , error ) {
156
+ res := filepath .Join (parent , subdir )
157
+ if ! strings .HasSuffix (parent , string (os .PathSeparator )) {
158
+ parent += string (os .PathSeparator )
159
+ }
160
+ if ! strings .HasPrefix (res , parent ) {
161
+ return res , fmt .Errorf ("unsafe path join: '%s' with '%s'" , parent , subdir )
162
+ }
163
+ return res , nil
164
+ }
0 commit comments