11package tool
22
33import (
4+ "fmt"
45 "io"
56 "io/fs"
67 "os"
7- stdpath "path"
8+ "path/filepath "
89 "strings"
910
1011 "github.com/OpenListTeam/OpenList/v4/internal/model"
@@ -40,13 +41,13 @@ func GenerateMetaTreeFromFolderTraversal(r ArchiveReader) (bool, []model.ObjTree
4041 isNewFolder := false
4142 if ! file .FileInfo ().IsDir () {
4243 // 先将 文件 添加到 所在的文件夹
43- dir = stdpath .Dir (name )
44+ dir = filepath .Dir (name )
4445 dirObj = dirMap [dir ]
4546 if dirObj == nil {
4647 isNewFolder = dir != "."
4748 dirObj = & model.ObjectTree {}
4849 dirObj .IsFolder = true
49- dirObj .Name = stdpath .Base (dir )
50+ dirObj .Name = filepath .Base (dir )
5051 dirObj .Modified = file .FileInfo ().ModTime ()
5152 dirMap [dir ] = dirObj
5253 }
@@ -64,28 +65,28 @@ func GenerateMetaTreeFromFolderTraversal(r ArchiveReader) (bool, []model.ObjTree
6465 dirMap [dir ] = dirObj
6566 }
6667 dirObj .IsFolder = true
67- dirObj .Name = stdpath .Base (dir )
68+ dirObj .Name = filepath .Base (dir )
6869 dirObj .Modified = file .FileInfo ().ModTime ()
6970 }
7071 if isNewFolder {
7172 // 将 文件夹 添加到 父文件夹
7273 // 考虑压缩包仅记录文件的路径,不记录文件夹
7374 // 循环创建所有父文件夹
74- parentDir := stdpath .Dir (dir )
75+ parentDir := filepath .Dir (dir )
7576 for {
7677 parentDirObj := dirMap [parentDir ]
7778 if parentDirObj == nil {
7879 parentDirObj = & model.ObjectTree {}
7980 if parentDir != "." {
8081 parentDirObj .IsFolder = true
81- parentDirObj .Name = stdpath .Base (parentDir )
82+ parentDirObj .Name = filepath .Base (parentDir )
8283 parentDirObj .Modified = file .FileInfo ().ModTime ()
8384 }
8485 dirMap [parentDir ] = parentDirObj
8586 }
8687 parentDirObj .Children = append (parentDirObj .Children , dirObj )
8788
88- parentDir = stdpath .Dir (parentDir )
89+ parentDir = filepath .Dir (parentDir )
8990 if dirMap [parentDir ] != nil {
9091 break
9192 }
@@ -127,7 +128,7 @@ func DecompressFromFolderTraversal(r ArchiveReader, outputPath string, args mode
127128 }
128129 } else {
129130 innerPath := strings .TrimPrefix (args .InnerPath , "/" )
130- innerBase := stdpath .Base (innerPath )
131+ innerBase := filepath .Base (innerPath )
131132 createdBaseDir := false
132133 for _ , file := range files {
133134 name := file .Name ()
@@ -138,7 +139,7 @@ func DecompressFromFolderTraversal(r ArchiveReader, outputPath string, args mode
138139 }
139140 break
140141 } else if strings .HasPrefix (name , innerPath + "/" ) {
141- targetPath := stdpath .Join (outputPath , innerBase )
142+ targetPath := filepath .Join (outputPath , innerBase )
142143 if ! createdBaseDir {
143144 err = os .Mkdir (targetPath , 0700 )
144145 if err != nil {
@@ -159,12 +160,16 @@ func DecompressFromFolderTraversal(r ArchiveReader, outputPath string, args mode
159160
160161func decompress (file SubFile , filePath , outputPath , password string ) error {
161162 targetPath := outputPath
162- dir , base := stdpath .Split (filePath )
163+ dir , base := filepath .Split (filePath )
163164 if dir != "" {
164- targetPath = stdpath .Join (targetPath , dir )
165- err := os .MkdirAll (targetPath , 0700 )
166- if err != nil {
167- return err
165+ targetPath = filepath .Join (targetPath , dir )
166+ if strings .HasPrefix (targetPath , outputPath + string (os .PathSeparator )) {
167+ err := os .MkdirAll (targetPath , 0700 )
168+ if err != nil {
169+ return err
170+ }
171+ } else {
172+ targetPath = outputPath
168173 }
169174 }
170175 if base != "" {
@@ -185,7 +190,11 @@ func _decompress(file SubFile, targetPath, password string, up model.UpdateProgr
185190 return err
186191 }
187192 defer func () { _ = rc .Close () }()
188- f , err := os .OpenFile (stdpath .Join (targetPath , file .FileInfo ().Name ()), os .O_WRONLY | os .O_CREATE | os .O_EXCL , 0600 )
193+ destPath := filepath .Join (targetPath , file .FileInfo ().Name ())
194+ if ! strings .HasPrefix (destPath , targetPath + string (os .PathSeparator )) {
195+ return fmt .Errorf ("illegal file path: %s" , file .FileInfo ().Name ())
196+ }
197+ f , err := os .OpenFile (destPath , os .O_WRONLY | os .O_CREATE | os .O_EXCL , 0600 )
189198 if err != nil {
190199 return err
191200 }
0 commit comments