Skip to content

Commit dec7fd3

Browse files
committed
Fix UnArchiver#isOverwrite not working as expected
Regression in efd980d changed the way UnArchiver#isOverwrite flag work. It is indented to indicate that UnArchiver should always override the existing entries. efd980d changed it to indicate whether existing file should be overridden if the entry is newer, while in this case the file should be always overridden. This commit returns the old behavior: if the entry is newer, override the existing file; if the entry is older, override the existing file only if isOverwrite is true. Fixes: #228
1 parent 0a5115c commit dec7fd3

File tree

2 files changed

+25
-32
lines changed

2 files changed

+25
-32
lines changed

src/main/java/org/codehaus/plexus/archiver/AbstractUnArchiver.java

+13-24
Original file line numberDiff line numberDiff line change
@@ -401,16 +401,18 @@ else if ( isDirectory )
401401
protected boolean shouldExtractEntry( File targetDirectory, File targetFileName, String entryName, Date entryDate ) throws IOException
402402
{
403403
// entryname | entrydate | filename | filedate | behavior
404-
// (1) readme.txt | 1970 | readme.txt | 2020 | never overwrite
405-
// (2) readme.txt | 2020 | readme.txt | 1970 | only overwrite when isOverWrite()
406-
// (3) README.txt | 1970 | readme.txt | 2020 | case-insensitive filesystem: warn + never overwrite
404+
// (1) readme.txt | 1970 | - | - | always extract if the file does not exist
405+
// (2) readme.txt | 1970 | readme.txt | 2020 | do not overwrite unless isOverwrite() is true
406+
// (3) readme.txt | 2020 | readme.txt | 1970 | always override when the file is older than the archive entry
407+
// (4) README.txt | 1970 | readme.txt | 2020 | case-insensitive filesystem: warn + do not overwrite unless isOverwrite()
407408
// case-sensitive filesystem: extract without warning
408-
// (4) README.txt | 2020 | readme.txt | 1970 | case-insensitive filesystem: warn + only overwrite when isOverWrite()
409+
// (5) README.txt | 2020 | readme.txt | 1970 | case-insensitive filesystem: warn + overwrite because entry is newer
409410
// case-sensitive filesystem: extract without warning
410411

411412
// The canonical file name follows the name of the archive entry, but takes into account the case-
412413
// sensitivity of the filesystem. So on a case-sensitive file system, file.exists() returns false for
413-
// scenario (3) and (4).
414+
// scenario (4) and (5).
415+
// No matter the case sensitivity of the file system, file.exists() returns false when there is no file with the same name (1).
414416
if ( !targetFileName.exists() )
415417
{
416418
return true;
@@ -423,33 +425,20 @@ protected boolean shouldExtractEntry( File targetDirectory, File targetFileName,
423425
targetDirectory.getCanonicalPath() + File.separatorChar,
424426
"" )
425427
+ suffix;
426-
boolean fileOnDiskIsNewerThanEntry = targetFileName.lastModified() >= entryDate.getTime();
428+
boolean fileOnDiskIsOlderThanEntry = targetFileName.lastModified() < entryDate.getTime();
427429
boolean differentCasing = !entryName.equals( relativeCanonicalDestPath );
428430

429-
String casingMessage = String.format( Locale.ENGLISH, "Archive entry '%s' and existing file '%s' names differ only by case."
430-
+ " This may lead to an unexpected outcome on case-insensitive filesystems.", entryName, canonicalDestPath );
431-
432-
// (1)
433-
if ( fileOnDiskIsNewerThanEntry )
434-
{
435-
// (3)
436-
if ( differentCasing )
437-
{
438-
getLogger().warn( casingMessage );
439-
casingMessageEmitted.incrementAndGet();
440-
}
441-
return false;
442-
}
443-
444-
// (4)
431+
// Warn for case (4) and (5) if the file system is case-insensitive
445432
if ( differentCasing )
446433
{
434+
String casingMessage = String.format( Locale.ENGLISH, "Archive entry '%s' and existing file '%s' names differ only by case."
435+
+ " This may lead to an unexpected outcome on case-insensitive filesystems.", entryName, canonicalDestPath );
447436
getLogger().warn( casingMessage );
448437
casingMessageEmitted.incrementAndGet();
449438
}
450439

451-
// (2)
452-
return isOverwrite();
440+
// Override the existing file if isOverwrite() is true or if the file on disk is older than the one in the archive
441+
return isOverwrite() || fileOnDiskIsOlderThanEntry;
453442
}
454443

455444
}

src/test/java/org/codehaus/plexus/archiver/AbstractUnArchiverTest.java

+12-8
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,14 @@ public void shouldExtractWhenFileOnDiskDoesNotExist( @TempDir File temporaryFol
9191
Date entryDate = new Date();
9292

9393
// when & then
94+
// always extract the file if it does not exist
95+
assertTrue( abstractUnArchiver.shouldExtractEntry( temporaryFolder, file, entryname, entryDate ) );
96+
abstractUnArchiver.setOverwrite( false );
9497
assertTrue( abstractUnArchiver.shouldExtractEntry( temporaryFolder, file, entryname, entryDate ) );
9598
}
9699

97100
@Test
98-
public void shouldNotExtractWhenFileOnDiskIsNewerThanEntryInArchive( @TempDir File temporaryFolder ) throws IOException
101+
public void shouldExtractWhenFileOnDiskIsNewerThanEntryInArchive( @TempDir File temporaryFolder ) throws IOException
99102
{
100103
// given
101104
File file = new File( temporaryFolder, "whatever.txt" );
@@ -105,11 +108,14 @@ public void shouldNotExtractWhenFileOnDiskIsNewerThanEntryInArchive( @TempDir Fi
105108
Date entryDate = new Date( 0 );
106109

107110
// when & then
111+
// if the file is newer than archive entry, extract only if overwrite is true (default)
112+
assertTrue( this.abstractUnArchiver.shouldExtractEntry( temporaryFolder, file, entryname, entryDate ) );
113+
abstractUnArchiver.setOverwrite( false );
108114
assertFalse( this.abstractUnArchiver.shouldExtractEntry( temporaryFolder, file, entryname, entryDate ) );
109115
}
110116

111117
@Test
112-
public void shouldNotExtractWhenFileOnDiskIsNewerThanEntryInArchive_andWarnAboutDifferentCasing( @TempDir File temporaryFolder )
118+
public void shouldExtractWhenFileOnDiskIsNewerThanEntryInArchive_andWarnAboutDifferentCasing( @TempDir File temporaryFolder )
113119
throws IOException
114120
{
115121
// given
@@ -120,7 +126,7 @@ public void shouldNotExtractWhenFileOnDiskIsNewerThanEntryInArchive_andWarnAbout
120126
Date entryDate = new Date( 0 );
121127

122128
// when & then
123-
assertFalse( this.abstractUnArchiver.shouldExtractEntry( temporaryFolder, file, entryname, entryDate ) );
129+
assertTrue( this.abstractUnArchiver.shouldExtractEntry( temporaryFolder, file, entryname, entryDate ) );
124130
assertTrue( this.abstractUnArchiver.casingMessageEmitted.get() > 0 );
125131
}
126132

@@ -135,12 +141,10 @@ public void shouldExtractWhenEntryInArchiveIsNewerThanFileOnDisk( @TempDir File
135141
Date entryDate = new Date( System.currentTimeMillis() );
136142

137143
// when & then
138-
this.abstractUnArchiver.setOverwrite( true );
144+
// always extract the file if the archive entry is newer than the file on disk
139145
assertTrue( this.abstractUnArchiver.shouldExtractEntry( temporaryFolder, file, entryname, entryDate ) );
140-
141-
// when & then
142146
this.abstractUnArchiver.setOverwrite( false );
143-
assertFalse( this.abstractUnArchiver.shouldExtractEntry( temporaryFolder, file, entryname, entryDate ) );
147+
assertTrue( this.abstractUnArchiver.shouldExtractEntry( temporaryFolder, file, entryname, entryDate ) );
144148
}
145149

146150
@Test
@@ -158,7 +162,7 @@ public void shouldExtractWhenEntryInArchiveIsNewerThanFileOnDiskAndWarnAboutDiff
158162
this.abstractUnArchiver.setOverwrite( true );
159163
assertTrue( this.abstractUnArchiver.shouldExtractEntry( temporaryFolder, file, entryname, entryDate ) );
160164
this.abstractUnArchiver.setOverwrite( false );
161-
assertFalse( this.abstractUnArchiver.shouldExtractEntry( temporaryFolder, file, entryname, entryDate ) );
165+
assertTrue( this.abstractUnArchiver.shouldExtractEntry( temporaryFolder, file, entryname, entryDate ) );
162166
assertTrue( this.abstractUnArchiver.casingMessageEmitted.get() > 0 );
163167
}
164168

0 commit comments

Comments
 (0)