Skip to content

Commit a080e0a

Browse files
Updated to always add the Info-ZIP Unicode Path Extra Field when creating an
archive using an encoding different from UTF-8 instead of only when a name is not encodeable. Additionally support that extra field when unarchiving. This closes #39
1 parent 61bd142 commit a080e0a

File tree

2 files changed

+80
-20
lines changed

2 files changed

+80
-20
lines changed

src/main/java/org/codehaus/plexus/archiver/zip/AbstractZipArchiver.java

+42-3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.apache.commons.compress.archivers.zip.ZipEncoding;
2323
import org.apache.commons.compress.archivers.zip.ZipEncodingHelper;
2424
import org.apache.commons.compress.parallel.InputStreamSupplier;
25+
import org.apache.commons.compress.utils.Charsets;
2526
import org.codehaus.plexus.archiver.AbstractArchiver;
2627
import org.codehaus.plexus.archiver.ArchiveEntry;
2728
import org.codehaus.plexus.archiver.Archiver;
@@ -41,6 +42,7 @@
4142
import java.io.InputStream;
4243
import java.io.OutputStream;
4344
import java.io.SequenceInputStream;
45+
import java.nio.charset.Charset;
4446
import java.util.Hashtable;
4547
import java.util.Stack;
4648
import java.util.concurrent.ExecutionException;
@@ -208,7 +210,6 @@ public boolean isFilesonly()
208210
return doFilesonly;
209211
}
210212

211-
212213
protected void execute()
213214
throws ArchiverException, IOException
214215
{
@@ -315,8 +316,7 @@ private void createArchiveMain()
315316
zipArchiveOutputStream =
316317
new ZipArchiveOutputStream( bufferedOutputStream( fileOutputStream( zipFile, "zip" ) ) );
317318
zipArchiveOutputStream.setEncoding( encoding );
318-
zipArchiveOutputStream.setCreateUnicodeExtraFields(
319-
ZipArchiveOutputStream.UnicodeExtraFieldPolicy.NOT_ENCODEABLE );
319+
zipArchiveOutputStream.setCreateUnicodeExtraFields( this.getUnicodeExtraFieldPolicy() );
320320
zipArchiveOutputStream.setMethod(
321321
doCompress ? ZipArchiveOutputStream.DEFLATED : ZipArchiveOutputStream.STORED );
322322

@@ -339,6 +339,45 @@ private void createArchiveMain()
339339
success = true;
340340
}
341341

342+
/**
343+
* Gets the {@code UnicodeExtraFieldPolicy} to apply.
344+
*
345+
* @return {@link ZipArchiveOutputStream.UnicodeExtraFieldPolicy.NOT_ENCODEABLE}, if the effective encoding is
346+
* UTF-8; {@link ZipArchiveOutputStream.UnicodeExtraFieldPolicy.ALWAYS}, if the effective encoding is not
347+
* UTF-8.
348+
*
349+
* @see #getEncoding()
350+
*/
351+
private ZipArchiveOutputStream.UnicodeExtraFieldPolicy getUnicodeExtraFieldPolicy()
352+
{
353+
// Copied from ZipEncodingHelper.isUTF8()
354+
String effectiveEncoding = this.getEncoding();
355+
356+
if ( effectiveEncoding == null )
357+
{
358+
effectiveEncoding = Charset.defaultCharset().name();
359+
}
360+
361+
boolean utf8 = Charsets.UTF_8.name().equalsIgnoreCase( effectiveEncoding );
362+
363+
if ( !utf8 )
364+
{
365+
for ( String alias : Charsets.UTF_8.aliases() )
366+
{
367+
if ( alias.equalsIgnoreCase( effectiveEncoding ) )
368+
{
369+
utf8 = true;
370+
break;
371+
}
372+
}
373+
}
374+
375+
return utf8
376+
? ZipArchiveOutputStream.UnicodeExtraFieldPolicy.NOT_ENCODEABLE
377+
: ZipArchiveOutputStream.UnicodeExtraFieldPolicy.ALWAYS;
378+
379+
}
380+
342381
/**
343382
* Add the given resources.
344383
*

src/main/java/org/codehaus/plexus/archiver/zip/AbstractZipUnArchiver.java

+38-17
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,21 @@
2020
import java.io.File;
2121
import java.io.IOException;
2222
import java.io.InputStream;
23+
import java.io.UnsupportedEncodingException;
2324
import java.net.URL;
2425
import java.util.Date;
2526
import java.util.Enumeration;
27+
import javax.annotation.Nonnull;
2628

29+
import org.apache.commons.compress.archivers.zip.UnicodePathExtraField;
2730
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
2831
import org.apache.commons.compress.archivers.zip.ZipFile;
2932
import org.apache.commons.compress.utils.IOUtils;
33+
3034
import org.codehaus.plexus.archiver.AbstractUnArchiver;
3135
import org.codehaus.plexus.archiver.ArchiverException;
3236
import org.codehaus.plexus.components.io.resources.PlexusIoResource;
3337

34-
import javax.annotation.Nonnull;
35-
3638
/**
3739
* @author <a href="mailto:[email protected]">Emmanuel Venisse</a>
3840
* @version $Id$
@@ -84,7 +86,20 @@ private static class ZipEntryFileInfo
8486

8587
public String getName()
8688
{
87-
return zipEntry.getName();
89+
try
90+
{
91+
final UnicodePathExtraField unicodePath =
92+
(UnicodePathExtraField) zipEntry.getExtraField( UnicodePathExtraField.UPATH_ID );
93+
94+
return unicodePath != null
95+
? new String( unicodePath.getUnicodeName(), "UTF-8" )
96+
: zipEntry.getName();
97+
98+
}
99+
catch ( final UnsupportedEncodingException e )
100+
{
101+
throw new AssertionError( e );
102+
}
88103
}
89104

90105
public boolean isDirectory()
@@ -141,27 +156,30 @@ protected void execute()
141156
InputStream in = null;
142157
try
143158
{
144-
zf = new org.apache.commons.compress.archivers.zip.ZipFile( getSourceFile(), encoding );
145-
final Enumeration e = zf.getEntries();
159+
zf = new org.apache.commons.compress.archivers.zip.ZipFile( getSourceFile(), encoding, true );
160+
final Enumeration e = zf.getEntriesInPhysicalOrder();
146161
while ( e.hasMoreElements() )
147162
{
148163
final ZipArchiveEntry ze = (ZipArchiveEntry) e.nextElement();
149164
final ZipEntryFileInfo fileInfo = new ZipEntryFileInfo( zf, ze );
150-
if ( isSelected( ze.getName(), fileInfo ) )
165+
if ( isSelected( fileInfo.getName(), fileInfo ) )
151166
{
152-
in = zf.getInputStream( ze );
153-
extractFileIfIncluded(getSourceFile(), getDestDirectory(), in, ze.getName(),
154-
new Date(ze.getTime()), ze.isDirectory(), ze.getUnixMode() != 0 ? ze.getUnixMode() : null,
155-
resolveSymlink( zf, ze ) );
167+
in = zf.getInputStream( ze );
168+
169+
extractFileIfIncluded( getSourceFile(), getDestDirectory(), in, fileInfo.getName(),
170+
new Date( ze.getTime() ), ze.isDirectory(),
171+
ze.getUnixMode() != 0 ? ze.getUnixMode() : null,
172+
resolveSymlink( zf, ze ) );
173+
156174
in.close();
157175
in = null;
158-
}
159-
160-
}
176+
}
177+
}
161178

162-
getLogger().debug( "expand complete" );
163179
zf.close();
164180
zf = null;
181+
182+
getLogger().debug( "expand complete" );
165183
}
166184
catch ( final IOException ioe )
167185
{
@@ -197,9 +215,9 @@ protected void execute( final String path, final File outputDirectory )
197215
InputStream in = null;
198216
try
199217
{
200-
zipFile = new org.apache.commons.compress.archivers.zip.ZipFile( getSourceFile(), encoding );
218+
zipFile = new org.apache.commons.compress.archivers.zip.ZipFile( getSourceFile(), encoding, true );
201219

202-
final Enumeration e = zipFile.getEntries();
220+
final Enumeration e = zipFile.getEntriesInPhysicalOrder();
203221

204222
while ( e.hasMoreElements() )
205223
{
@@ -213,9 +231,12 @@ protected void execute( final String path, final File outputDirectory )
213231
if ( ze.getName().startsWith( path ) )
214232
{
215233
in = zipFile.getInputStream( ze );
234+
216235
extractFileIfIncluded( getSourceFile(), outputDirectory, in,
217236
ze.getName(), new Date( ze.getTime() ), ze.isDirectory(),
218-
ze.getUnixMode() != 0 ? ze.getUnixMode() : null, resolveSymlink( zipFile, ze ) );
237+
ze.getUnixMode() != 0 ? ze.getUnixMode() : null,
238+
resolveSymlink( zipFile, ze ) );
239+
219240
in.close();
220241
in = null;
221242
}

0 commit comments

Comments
 (0)