@@ -196,6 +196,49 @@ func TestBreakouts(t *testing.T) {
196
196
return nil
197
197
}
198
198
errFileDiff := errors .New ("files differ" )
199
+
200
+ isSymlinkFile := func (f string ) func (string ) error {
201
+ return func (root string ) error {
202
+ fi , err := os .Lstat (filepath .Join (root , f ))
203
+ if err != nil {
204
+ return err
205
+ }
206
+
207
+ if got := fi .Mode () & os .ModeSymlink ; got != os .ModeSymlink {
208
+ return errors .Errorf ("%s should be symlink" , fi .Name ())
209
+ }
210
+ return nil
211
+ }
212
+ }
213
+
214
+ sameSymlinkFile := func (f1 , f2 string ) func (string ) error {
215
+ checkF1 , checkF2 := isSymlinkFile (f1 ), isSymlinkFile (f2 )
216
+ return func (root string ) error {
217
+ if err := checkF1 (root ); err != nil {
218
+ return err
219
+ }
220
+
221
+ if err := checkF2 (root ); err != nil {
222
+ return err
223
+ }
224
+
225
+ t1 , err := os .Readlink (filepath .Join (root , f1 ))
226
+ if err != nil {
227
+ return err
228
+ }
229
+
230
+ t2 , err := os .Readlink (filepath .Join (root , f2 ))
231
+ if err != nil {
232
+ return err
233
+ }
234
+
235
+ if t1 != t2 {
236
+ return errors .Wrapf (errFileDiff , "%#v and %#v" , t1 , t2 )
237
+ }
238
+ return nil
239
+ }
240
+ }
241
+
199
242
sameFile := func (f1 , f2 string ) func (string ) error {
200
243
return func (root string ) error {
201
244
p1 , err := fs .RootPath (root , f1 )
@@ -406,6 +449,16 @@ func TestBreakouts(t *testing.T) {
406
449
),
407
450
validator : sameFile ("localpasswd" , "/etc/passwd" ),
408
451
},
452
+ {
453
+ name : "HardlinkSymlinkBeforeCreateTarget" ,
454
+ w : TarAll (
455
+ tc .Dir ("etc" , 0770 ),
456
+ tc .Symlink ("/etc/passwd" , "localpasswd" ),
457
+ tc .Link ("localpasswd" , "localpasswd-dup" ),
458
+ tc .File ("/etc/passwd" , []byte ("after" ), 0644 ),
459
+ ),
460
+ validator : sameFile ("localpasswd-dup" , "/etc/passwd" ),
461
+ },
409
462
{
410
463
name : "HardlinkSymlinkRelative" ,
411
464
w : TarAll (
@@ -414,7 +467,10 @@ func TestBreakouts(t *testing.T) {
414
467
tc .Symlink ("../../../../../etc/passwd" , "passwdlink" ),
415
468
tc .Link ("/passwdlink" , "localpasswd" ),
416
469
),
417
- validator : sameFile ("/localpasswd" , "/etc/passwd" ),
470
+ validator : all (
471
+ sameSymlinkFile ("/localpasswd" , "/passwdlink" ),
472
+ sameFile ("/localpasswd" , "/etc/passwd" ),
473
+ ),
418
474
},
419
475
{
420
476
name : "HardlinkSymlinkAbsolute" ,
@@ -424,7 +480,10 @@ func TestBreakouts(t *testing.T) {
424
480
tc .Symlink ("/etc/passwd" , "passwdlink" ),
425
481
tc .Link ("/passwdlink" , "localpasswd" ),
426
482
),
427
- validator : sameFile ("/localpasswd" , "/etc/passwd" ),
483
+ validator : all (
484
+ sameSymlinkFile ("/localpasswd" , "/passwdlink" ),
485
+ sameFile ("/localpasswd" , "/etc/passwd" ),
486
+ ),
428
487
},
429
488
{
430
489
name : "SymlinkParentDirectory" ,
0 commit comments