@@ -118,7 +118,10 @@ func (u *UIUpdater) downloadUI() error {
118
118
119
119
tmpDir := C .Path .Resolve ("downloadUI.tmp" )
120
120
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 )
122
125
if err != nil {
123
126
return fmt .Errorf ("can't extract compressed file: %w" , err )
124
127
}
@@ -136,8 +139,8 @@ func (u *UIUpdater) downloadUI() error {
136
139
return fmt .Errorf ("prepare UI path failed: %w" , err )
137
140
}
138
141
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
141
144
if err != nil {
142
145
return fmt .Errorf ("move UI folder failed: %w" , err )
143
146
}
@@ -154,63 +157,19 @@ func (u *UIUpdater) prepareUIPath() error {
154
157
return nil
155
158
}
156
159
157
- func unzip (data []byte , dest string ) ( string , error ) {
160
+ func unzip (data []byte , dest string ) error {
158
161
r , err := zip .NewReader (bytes .NewReader (data ), int64 (len (data )))
159
162
if err != nil {
160
- return "" , err
163
+ return err
161
164
}
162
165
163
166
// 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
- }
203
167
204
168
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 )
211
170
212
171
if ! inDest (fpath , dest ) {
213
- return "" , fmt .Errorf ("invalid file path: %s" , fpath )
172
+ return fmt .Errorf ("invalid file path: %s" , fpath )
214
173
}
215
174
info := f .FileInfo ()
216
175
if info .IsDir () {
@@ -221,128 +180,77 @@ func unzip(data []byte, dest string) (string, error) {
221
180
continue // disallow symlink
222
181
}
223
182
if err = os .MkdirAll (filepath .Dir (fpath ), os .ModePerm ); err != nil {
224
- return "" , err
183
+ return err
225
184
}
226
185
outFile , err := os .OpenFile (fpath , os .O_WRONLY | os .O_CREATE | os .O_TRUNC , f .Mode ())
227
186
if err != nil {
228
- return "" , err
187
+ return err
229
188
}
230
189
rc , err := f .Open ()
231
190
if err != nil {
232
- return "" , err
191
+ return err
233
192
}
234
193
_ , err = io .Copy (outFile , rc )
235
194
outFile .Close ()
236
195
rc .Close ()
237
196
if err != nil {
238
- return "" , err
197
+ return err
239
198
}
240
199
}
241
- return extractedFolder , nil
200
+ return nil
242
201
}
243
202
244
- func untgz (data []byte , dest string ) ( string , error ) {
203
+ func untgz (data []byte , dest string ) error {
245
204
gzr , err := gzip .NewReader (bytes .NewReader (data ))
246
205
if err != nil {
247
- return "" , err
206
+ return err
248
207
}
249
208
defer gzr .Close ()
250
209
251
210
tr := tar .NewReader (gzr )
252
211
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
-
288
212
_ = gzr .Reset (bytes .NewReader (data ))
289
213
tr = tar .NewReader (gzr )
290
214
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
-
302
215
for {
303
216
header , err := tr .Next ()
304
217
if err == io .EOF {
305
218
break
306
219
}
307
220
if err != nil {
308
- return "" , err
221
+ return err
309
222
}
310
223
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 )
317
225
318
226
if ! inDest (fpath , dest ) {
319
- return "" , fmt .Errorf ("invalid file path: %s" , fpath )
227
+ return fmt .Errorf ("invalid file path: %s" , fpath )
320
228
}
321
229
322
230
switch header .Typeflag {
323
231
case tar .TypeDir :
324
232
if err = os .MkdirAll (fpath , os .FileMode (header .Mode )); err != nil {
325
- return "" , err
233
+ return err
326
234
}
327
235
case tar .TypeReg :
328
236
if err = os .MkdirAll (filepath .Dir (fpath ), os .ModePerm ); err != nil {
329
- return "" , err
237
+ return err
330
238
}
331
239
outFile , err := os .OpenFile (fpath , os .O_WRONLY | os .O_CREATE | os .O_TRUNC , os .FileMode (header .Mode ))
332
240
if err != nil {
333
- return "" , err
241
+ return err
334
242
}
335
243
if _ , err := io .Copy (outFile , tr ); err != nil {
336
244
outFile .Close ()
337
- return "" , err
245
+ return err
338
246
}
339
247
outFile .Close ()
340
248
}
341
249
}
342
- return extractedFolder , nil
250
+ return nil
343
251
}
344
252
345
- func extract (data []byte , dest string ) ( string , error ) {
253
+ func extract (data []byte , dest string ) error {
346
254
fileType := detectFileType (data )
347
255
log .Debugln ("compression Type: %s" , fileType )
348
256
switch fileType {
@@ -351,7 +259,7 @@ func extract(data []byte, dest string) (string, error) {
351
259
case typeTarGzip :
352
260
return untgz (data , dest )
353
261
default :
354
- return "" , fmt .Errorf ("unknown or unsupported file type" )
262
+ return fmt .Errorf ("unknown or unsupported file type" )
355
263
}
356
264
}
357
265
@@ -393,6 +301,15 @@ func moveDir(src string, dst string) error {
393
301
return err
394
302
}
395
303
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
+
396
313
for _ , dirEntry := range dirEntryList {
397
314
err = os .Rename (filepath .Join (src , dirEntry .Name ()), filepath .Join (dst , dirEntry .Name ()))
398
315
if err != nil {
0 commit comments