Skip to content

Commit a9eb01f

Browse files
committed
update
1 parent c879cfb commit a9eb01f

File tree

3 files changed

+85
-21
lines changed

3 files changed

+85
-21
lines changed

archive.go

+64-20
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,16 @@ func Zip(srcDirPath string, destFilePath string, args ...*regexp.Regexp) (n int6
5353
relativePath := strings.TrimPrefix(path, root)
5454
relativePath = strings.Replace(relativePath, `\`, `/`, -1)
5555
relativePath = strings.TrimPrefix(relativePath, `/`)
56-
f, err := w.Create(relativePath)
56+
fw, err := w.Create(relativePath)
5757
if err != nil {
5858
return err
5959
}
6060
sf, err := os.Open(path)
6161
if err != nil {
6262
return err
6363
}
64-
defer sf.Close()
65-
_, err = io.Copy(f, sf)
64+
_, err = io.Copy(fw, sf)
65+
sf.Close()
6666
return err
6767
})
6868

@@ -78,6 +78,25 @@ func Zip(srcDirPath string, destFilePath string, args ...*regexp.Regexp) (n int6
7878
return
7979
}
8080

81+
func IllegalFilePath(path string) bool {
82+
var dots int
83+
for _, c := range path {
84+
switch c {
85+
case '.':
86+
dots++
87+
case '/':
88+
fallthrough
89+
case '\\':
90+
if dots > 1 {
91+
return true
92+
}
93+
default:
94+
dots = 0
95+
}
96+
}
97+
return false
98+
}
99+
81100
// Unzip unzips .zip file to 'destPath'.
82101
// It returns error when fail to finish operation.
83102
func Unzip(srcPath, destPath string) error {
@@ -90,24 +109,34 @@ func Unzip(srcPath, destPath string) error {
90109

91110
// Iterate through the files in the archive
92111
for _, f := range r.File {
93-
// Get files from archive
94-
rc, err := f.Open()
95-
if err != nil {
96-
return err
112+
if IllegalFilePath(f.Name) {
113+
return fmt.Errorf("illegal file path in %s: %v", filepath.Base(srcPath), f.Name)
97114
}
98115

99-
dir := filepath.Dir(f.Name)
100-
// Create directory before create file
101-
os.MkdirAll(destPath+"/"+dir, os.ModePerm)
102-
116+
fullPath := filepath.Join(destPath, f.Name)
103117
if f.FileInfo().IsDir() {
118+
if err = os.MkdirAll(fullPath, f.Mode()); err != nil {
119+
return err
120+
}
104121
continue
105122
}
106123

124+
dir := filepath.Dir(f.Name)
125+
// Create directory before create file
126+
if err = os.MkdirAll(filepath.Join(destPath, dir), os.ModePerm); err != nil {
127+
return err
128+
}
129+
130+
// Get files from archive
131+
rc, err := f.Open()
132+
if err != nil {
133+
return err
134+
}
107135
// Write data to file
108136
var fw *os.File
109-
fw, err = os.Create(filepath.Join(destPath, f.Name))
137+
fw, err = os.OpenFile(fullPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
110138
if err != nil {
139+
rc.Close()
111140
return err
112141
}
113142
_, err = io.Copy(fw, rc)
@@ -163,6 +192,7 @@ func tarGz(gw *gzip.Writer, srcDirPath string, args ...*regexp.Regexp) error {
163192
return err
164193
}
165194
fi, err := f.Stat()
195+
f.Close()
166196
if err != nil {
167197
return err
168198
}
@@ -177,7 +207,7 @@ func tarGz(gw *gzip.Writer, srcDirPath string, args ...*regexp.Regexp) error {
177207
}
178208
// handle source directory
179209
fmt.Println("Cerating tar.gz from directory...")
180-
if err := tarGzDir(srcDirPath, filepath.Base(srcDirPath), tw, regexpFileName, regexpIgnoreFile); err != nil {
210+
if err := tarGzDir(srcDirPath, `.`, tw, regexpFileName, regexpIgnoreFile); err != nil {
181211
return err
182212
}
183213
} else {
@@ -286,7 +316,9 @@ func tarGzFile(srcFile string, recPath string, tw *tar.Writer, fi os.FileInfo) e
286316
// It returns error when fail to finish operation.
287317
func UnTarGz(srcFilePath string, destDirPath string) ([]string, error) {
288318
// Create destination directory
289-
os.Mkdir(destDirPath, os.ModePerm)
319+
if err := os.MkdirAll(destDirPath, os.ModePerm); err != nil {
320+
return nil, err
321+
}
290322

291323
fr, err := os.Open(srcFilePath)
292324
if err != nil {
@@ -312,23 +344,35 @@ func UnTarGz(srcFilePath string, destDirPath string) ([]string, error) {
312344
break
313345
}
314346

347+
if IllegalFilePath(hdr.Name) {
348+
return nil, fmt.Errorf("illegal file path in %s: %v", filepath.Base(srcFilePath), hdr.Name)
349+
}
350+
fullPath := filepath.Join(destDirPath, hdr.Name)
351+
mode := hdr.FileInfo().Mode()
352+
315353
// Check if it is directory or file
316354
if hdr.Typeflag != tar.TypeDir {
317355
// Get files from archive
318356
// Create directory before create file
319357
dir := filepath.Dir(hdr.Name)
320-
os.MkdirAll(destDirPath+"/"+dir, os.ModePerm)
321-
dirs = AppendStr(dirs, dir)
358+
if err = os.MkdirAll(filepath.Join(destDirPath, dir), os.ModePerm); err != nil {
359+
return nil, err
360+
}
322361

323362
// Write data to file
324-
fw, _ := os.Create(destDirPath + "/" + hdr.Name)
363+
var fw *os.File
364+
fw, err = os.OpenFile(fullPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, mode)
325365
if err != nil {
326366
return nil, err
327367
}
328368
_, err = io.Copy(fw, tr)
329-
if err != nil {
330-
return nil, err
331-
}
369+
fw.Close()
370+
} else {
371+
dirs = AppendStr(dirs, fullPath)
372+
err = os.MkdirAll(fullPath, mode)
373+
}
374+
if err != nil {
375+
return nil, err
332376
}
333377
}
334378
return dirs, nil

archive_test.go

+19
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com
22

33
import (
44
"os"
5+
"path/filepath"
56
"testing"
67

78
"github.com/stretchr/testify/assert"
@@ -15,4 +16,22 @@ func TestZip(t *testing.T) {
1516

1617
err = Unzip(`testdata/test.zip`, `testdata/unarchive`)
1718
assert.NoError(t, err)
19+
20+
assert.Equal(t, `/a/b/c`, filepath.Dir(`/a/b/c/..a.txt`))
21+
assert.Equal(t, `/a/b`, filepath.Dir(`/a/b/c/../a.txt`))
22+
assert.Equal(t, `/abc/a/b/a.txt`, filepath.Join(`/abc`, `/a/b/c/../a.txt`))
23+
assert.Equal(t, `/abc/a\b\c\..\a.txt`, filepath.Join(`/abc`, `/a\b\c\..\a.txt`))
24+
assert.Equal(t, `/abc/a/b/c/..a.txt`, filepath.Join(`/abc`, `/a/b/c/..a.txt`))
25+
assert.True(t, IllegalFilePath(`a/b/c/../a.txt`))
26+
assert.True(t, IllegalFilePath(`a/b/c/..\a.txt`))
27+
assert.False(t, IllegalFilePath(`a/b/c/..a.txt`))
28+
}
29+
30+
func TestTarGz(t *testing.T) {
31+
MkdirAll(`testdata`, os.ModePerm)
32+
err := TarGz(`./encoding`, `testdata/test.tar.gz`)
33+
assert.NoError(t, err)
34+
35+
_, err = UnTarGz(`testdata/test.tar.gz`, `testdata/unarchive`)
36+
assert.NoError(t, err)
1837
}

range_downloader.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ func RangeDownload(url string, saveTo string, args ...int) error {
4242
outfile, err = os.Create(saveTo)
4343
}
4444
} else {
45-
stat, err := outfile.Stat()
45+
var stat os.FileInfo
46+
stat, err = outfile.Stat()
4647
if err == nil {
4748
outfile.Seek(stat.Size(), 0)
4849
startByte = stat.Size()

0 commit comments

Comments
 (0)