@@ -118,7 +118,10 @@ func (u *UIUpdater) downloadUI() error {
118118
119119 tmpDir := C .Path .Resolve ("downloadUI.tmp" )
120120 defer os .RemoveAll (tmpDir )
121- extractedFolder , err := extract (data , tmpDir )
121+
122+ os .RemoveAll (tmpDir ) // cleanup tmp dir before extract
123+ log .Debugln ("extractedFolder: %s" , tmpDir )
124+ err = extract (data , tmpDir )
122125 if err != nil {
123126 return fmt .Errorf ("can't extract compressed file: %w" , err )
124127 }
@@ -136,8 +139,8 @@ func (u *UIUpdater) downloadUI() error {
136139 return fmt .Errorf ("prepare UI path failed: %w" , err )
137140 }
138141
139- log .Debugln ("moveFolder from %s to %s" , extractedFolder , u .externalUIPath )
140- err = moveDir (extractedFolder , u .externalUIPath ) // move files from tmp to target
142+ log .Debugln ("moveFolder from %s to %s" , tmpDir , u .externalUIPath )
143+ err = moveDir (tmpDir , u .externalUIPath ) // move files from tmp to target
141144 if err != nil {
142145 return fmt .Errorf ("move UI folder failed: %w" , err )
143146 }
@@ -154,63 +157,19 @@ func (u *UIUpdater) prepareUIPath() error {
154157 return nil
155158}
156159
157- func unzip (data []byte , dest string ) ( string , error ) {
160+ func unzip (data []byte , dest string ) error {
158161 r , err := zip .NewReader (bytes .NewReader (data ), int64 (len (data )))
159162 if err != nil {
160- return "" , err
163+ return err
161164 }
162165
163166 // check whether or not only exists singleRoot dir
164- rootDir := ""
165- isSingleRoot := true
166- rootItemCount := 0
167- for _ , f := range r .File {
168- parts := strings .Split (strings .Trim (f .Name , "/" ), "/" )
169- if len (parts ) == 0 {
170- continue
171- }
172-
173- if len (parts ) == 1 {
174- isDir := strings .HasSuffix (f .Name , "/" )
175- if ! isDir {
176- isSingleRoot = false
177- break
178- }
179-
180- if rootDir == "" {
181- rootDir = parts [0 ]
182- }
183- rootItemCount ++
184- }
185- }
186-
187- if rootItemCount != 1 {
188- isSingleRoot = false
189- }
190-
191- // build the dir of extraction
192- var extractedFolder string
193- if isSingleRoot && rootDir != "" {
194- // if the singleRoot, use it directly
195- log .Debugln ("Match the singleRoot" )
196- extractedFolder = filepath .Join (dest , rootDir )
197- log .Debugln ("extractedFolder: %s" , extractedFolder )
198- } else {
199- log .Debugln ("Match the multiRoot" )
200- extractedFolder = dest
201- log .Debugln ("extractedFolder: %s" , extractedFolder )
202- }
203167
204168 for _ , f := range r .File {
205- var fpath string
206- if isSingleRoot && rootDir != "" {
207- fpath = filepath .Join (dest , f .Name )
208- } else {
209- fpath = filepath .Join (extractedFolder , f .Name )
210- }
169+ fpath := filepath .Join (dest , f .Name )
211170
212171 if ! inDest (fpath , dest ) {
213- return "" , fmt .Errorf ("invalid file path: %s" , fpath )
172+ return fmt .Errorf ("invalid file path: %s" , fpath )
214173 }
215174 info := f .FileInfo ()
216175 if info .IsDir () {
@@ -221,128 +180,77 @@ func unzip(data []byte, dest string) (string, error) {
221180 continue // disallow symlink
222181 }
223182 if err = os .MkdirAll (filepath .Dir (fpath ), os .ModePerm ); err != nil {
224- return "" , err
183+ return err
225184 }
226185 outFile , err := os .OpenFile (fpath , os .O_WRONLY | os .O_CREATE | os .O_TRUNC , f .Mode ())
227186 if err != nil {
228- return "" , err
187+ return err
229188 }
230189 rc , err := f .Open ()
231190 if err != nil {
232- return "" , err
191+ return err
233192 }
234193 _ , err = io .Copy (outFile , rc )
235194 outFile .Close ()
236195 rc .Close ()
237196 if err != nil {
238- return "" , err
197+ return err
239198 }
240199 }
241- return extractedFolder , nil
200+ return nil
242201}
243202
244- func untgz (data []byte , dest string ) ( string , error ) {
203+ func untgz (data []byte , dest string ) error {
245204 gzr , err := gzip .NewReader (bytes .NewReader (data ))
246205 if err != nil {
247- return "" , err
206+ return err
248207 }
249208 defer gzr .Close ()
250209
251210 tr := tar .NewReader (gzr )
252211
253- rootDir := ""
254- isSingleRoot := true
255- rootItemCount := 0
256- for {
257- header , err := tr .Next ()
258- if err == io .EOF {
259- break
260- }
261- if err != nil {
262- return "" , err
263- }
264-
265- parts := strings .Split (cleanTarPath (header .Name ), string (os .PathSeparator ))
266- if len (parts ) == 0 {
267- continue
268- }
269-
270- if len (parts ) == 1 {
271- isDir := header .Typeflag == tar .TypeDir
272- if ! isDir {
273- isSingleRoot = false
274- break
275- }
276-
277- if rootDir == "" {
278- rootDir = parts [0 ]
279- }
280- rootItemCount ++
281- }
282- }
283-
284- if rootItemCount != 1 {
285- isSingleRoot = false
286- }
287-
288212 _ = gzr .Reset (bytes .NewReader (data ))
289213 tr = tar .NewReader (gzr )
290214
291- var extractedFolder string
292- if isSingleRoot && rootDir != "" {
293- log .Debugln ("Match the singleRoot" )
294- extractedFolder = filepath .Join (dest , rootDir )
295- log .Debugln ("extractedFolder: %s" , extractedFolder )
296- } else {
297- log .Debugln ("Match the multiRoot" )
298- extractedFolder = dest
299- log .Debugln ("extractedFolder: %s" , extractedFolder )
300- }
301-
302215 for {
303216 header , err := tr .Next ()
304217 if err == io .EOF {
305218 break
306219 }
307220 if err != nil {
308- return "" , err
221+ return err
309222 }
310223
311- var fpath string
312- if isSingleRoot && rootDir != "" {
313- fpath = filepath .Join (dest , cleanTarPath (header .Name ))
314- } else {
315- fpath = filepath .Join (extractedFolder , cleanTarPath (header .Name ))
316- }
224+ fpath := filepath .Join (dest , header .Name )
317225
318226 if ! inDest (fpath , dest ) {
319- return "" , fmt .Errorf ("invalid file path: %s" , fpath )
227+ return fmt .Errorf ("invalid file path: %s" , fpath )
320228 }
321229
322230 switch header .Typeflag {
323231 case tar .TypeDir :
324232 if err = os .MkdirAll (fpath , os .FileMode (header .Mode )); err != nil {
325- return "" , err
233+ return err
326234 }
327235 case tar .TypeReg :
328236 if err = os .MkdirAll (filepath .Dir (fpath ), os .ModePerm ); err != nil {
329- return "" , err
237+ return err
330238 }
331239 outFile , err := os .OpenFile (fpath , os .O_WRONLY | os .O_CREATE | os .O_TRUNC , os .FileMode (header .Mode ))
332240 if err != nil {
333- return "" , err
241+ return err
334242 }
335243 if _ , err := io .Copy (outFile , tr ); err != nil {
336244 outFile .Close ()
337- return "" , err
245+ return err
338246 }
339247 outFile .Close ()
340248 }
341249 }
342- return extractedFolder , nil
250+ return nil
343251}
344252
345- func extract (data []byte , dest string ) ( string , error ) {
253+ func extract (data []byte , dest string ) error {
346254 fileType := detectFileType (data )
347255 log .Debugln ("compression Type: %s" , fileType )
348256 switch fileType {
@@ -351,7 +259,7 @@ func extract(data []byte, dest string) (string, error) {
351259 case typeTarGzip :
352260 return untgz (data , dest )
353261 default :
354- return "" , fmt .Errorf ("unknown or unsupported file type" )
262+ return fmt .Errorf ("unknown or unsupported file type" )
355263 }
356264}
357265
@@ -393,6 +301,15 @@ func moveDir(src string, dst string) error {
393301 return err
394302 }
395303
304+ if len (dirEntryList ) == 1 && dirEntryList [0 ].IsDir () {
305+ src = filepath .Join (src , dirEntryList [0 ].Name ())
306+ log .Debugln ("match the singleRoot: %s" , src )
307+ dirEntryList , err = os .ReadDir (src )
308+ if err != nil {
309+ return err
310+ }
311+ }
312+
396313 for _ , dirEntry := range dirEntryList {
397314 err = os .Rename (filepath .Join (src , dirEntry .Name ()), filepath .Join (dst , dirEntry .Name ()))
398315 if err != nil {
0 commit comments