git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@677592 13f79535-47bb-0310-9956-ffa450edef68master
@@ -58,7 +58,9 @@ Changes that could break older environments: | |||||
passed in a null or empty InputStream to read from. | passed in a null or empty InputStream to read from. | ||||
Bugzilla Report 32200 | Bugzilla Report 32200 | ||||
* <unzip> will now fail on archives with an empty central directory. | |||||
* <unzip> and <untar> will now fail on empty archives (or ZIP | |||||
archives with an empty central directory). | |||||
set failOnEmptyArchive to false to restore the old behavior. | |||||
Bugzilla report 35000. | Bugzilla report 35000. | ||||
Fixed bugs: | Fixed bugs: | ||||
@@ -110,7 +110,12 @@ archive.</p> | |||||
encoding.</td> | encoding.</td> | ||||
<td align="center" valign="top">No</td> | <td align="center" valign="top">No</td> | ||||
</tr> | </tr> | ||||
<tr> | |||||
<td valign="top">failOnEmptyArchive</td> | |||||
<td valign="top">whether trying to extract an empty archive is an | |||||
error. <em>since Ant 1.8.0</em></td> | |||||
<td valign="top" align="center">No, defaults to true</td> | |||||
</tr> | |||||
</table> | </table> | ||||
<h3>Examples</h3> | <h3>Examples</h3> | ||||
<pre> | <pre> | ||||
@@ -66,6 +66,7 @@ public class Expand extends Task { | |||||
private Vector patternsets = new Vector(); | private Vector patternsets = new Vector(); | ||||
private Union resources = new Union(); | private Union resources = new Union(); | ||||
private boolean resourcesSpecified = false; | private boolean resourcesSpecified = false; | ||||
private boolean failOnEmptyArchive = true; | |||||
private static final String NATIVE_ENCODING = "native-encoding"; | private static final String NATIVE_ENCODING = "native-encoding"; | ||||
@@ -75,6 +76,24 @@ public class Expand extends Task { | |||||
private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); | private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); | ||||
/** | |||||
* Whether try ing to expand an empty archive would be an error. | |||||
* | |||||
* @since Ant 1.8.0 | |||||
*/ | |||||
public void setFailOnEmptyArchive(boolean b) { | |||||
failOnEmptyArchive = b; | |||||
} | |||||
/** | |||||
* Whether try ing to expand an empty archive would be an error. | |||||
* | |||||
* @since Ant 1.8.0 | |||||
*/ | |||||
public boolean getFailOnEmptyArchive() { | |||||
return failOnEmptyArchive; | |||||
} | |||||
/** | /** | ||||
* Do the work. | * Do the work. | ||||
* | * | ||||
@@ -140,7 +159,7 @@ public class Expand extends Task { | |||||
getLocation()); | getLocation()); | ||||
} | } | ||||
try { | try { | ||||
zf = new ZipFile(srcF, encoding); | |||||
zf = new ZipFile(srcF, encoding, failOnEmptyArchive); | |||||
Enumeration e = zf.getEntries(); | Enumeration e = zf.getEntries(); | ||||
while (e.hasMoreElements()) { | while (e.hasMoreElements()) { | ||||
ZipEntry ze = (ZipEntry) e.nextElement(); | ZipEntry ze = (ZipEntry) e.nextElement(); | ||||
@@ -142,12 +142,17 @@ public class Untar extends Expand { | |||||
new BufferedInputStream(stream))); | new BufferedInputStream(stream))); | ||||
log("Expanding: " + name + " into " + dir, Project.MSG_INFO); | log("Expanding: " + name + " into " + dir, Project.MSG_INFO); | ||||
TarEntry te = null; | TarEntry te = null; | ||||
boolean empty = true; | |||||
FileNameMapper mapper = getMapper(); | FileNameMapper mapper = getMapper(); | ||||
while ((te = tis.getNextEntry()) != null) { | while ((te = tis.getNextEntry()) != null) { | ||||
empty = false; | |||||
extractFile(FileUtils.getFileUtils(), null, dir, tis, | extractFile(FileUtils.getFileUtils(), null, dir, tis, | ||||
te.getName(), te.getModTime(), | te.getName(), te.getModTime(), | ||||
te.isDirectory(), mapper); | te.isDirectory(), mapper); | ||||
} | } | ||||
if (empty && getFailOnEmptyArchive()) { | |||||
throw new BuildException("archive is empty"); | |||||
} | |||||
log("expand complete", Project.MSG_VERBOSE); | log("expand complete", Project.MSG_VERBOSE); | ||||
} finally { | } finally { | ||||
FileUtils.close(tis); | FileUtils.close(tis); | ||||
@@ -146,10 +146,78 @@ public class ZipFile { | |||||
* @throws IOException if an error occurs while reading the file. | * @throws IOException if an error occurs while reading the file. | ||||
*/ | */ | ||||
public ZipFile(File f, String encoding) throws IOException { | public ZipFile(File f, String encoding) throws IOException { | ||||
this(f, encoding, false); | |||||
} | |||||
/** | |||||
* Opens the given file for reading, assuming the platform's | |||||
* native encoding for file names. | |||||
* | |||||
* @param f the archive. | |||||
* @param mustNotBeEmpty whether an empty central directory should | |||||
* case an error | |||||
* | |||||
* @throws IOException if an error occurs while reading the file. | |||||
* | |||||
* @since Ant 1.8.0 | |||||
*/ | |||||
public ZipFile(File f, boolean mustNotBeEmpty) throws IOException { | |||||
this(f, null, mustNotBeEmpty); | |||||
} | |||||
/** | |||||
* Opens the given file for reading, assuming the platform's | |||||
* native encoding for file names. | |||||
* | |||||
* @param name name of the archive. | |||||
* @param mustNotBeEmpty whether an empty central directory should | |||||
* case an error | |||||
* | |||||
* @throws IOException if an error occurs while reading the file. | |||||
* | |||||
* @since Ant 1.8.0 | |||||
*/ | |||||
public ZipFile(String name, boolean mustNotBeEmpty) throws IOException { | |||||
this(new File(name), null, mustNotBeEmpty); | |||||
} | |||||
/** | |||||
* Opens the given file for reading, assuming the specified | |||||
* encoding for file names. | |||||
* | |||||
* @param name name of the archive. | |||||
* @param encoding the encoding to use for file names | |||||
* @param mustNotBeEmpty whether an empty central directory should | |||||
* case an error | |||||
* | |||||
* @throws IOException if an error occurs while reading the file. | |||||
* | |||||
* @since Ant 1.8.0 | |||||
*/ | |||||
public ZipFile(String name, String encoding, | |||||
boolean mustNotBeEmpty) throws IOException { | |||||
this(new File(name), encoding, mustNotBeEmpty); | |||||
} | |||||
/** | |||||
* Opens the given file for reading, assuming the specified | |||||
* encoding for file names. | |||||
* | |||||
* @param f the archive. | |||||
* @param encoding the encoding to use for file names | |||||
* @param mustNotBeEmpty whether an empty central directory should | |||||
* case an error | |||||
* | |||||
* @throws IOException if an error occurs while reading the file. | |||||
* | |||||
* @since Ant 1.8.0 | |||||
*/ | |||||
public ZipFile(File f, String encoding, | |||||
boolean mustNotBeEmpty) throws IOException { | |||||
this.encoding = encoding; | this.encoding = encoding; | ||||
archive = new RandomAccessFile(f, "r"); | archive = new RandomAccessFile(f, "r"); | ||||
try { | try { | ||||
populateFromCentralDirectory(); | |||||
populateFromCentralDirectory(mustNotBeEmpty); | |||||
resolveLocalFileHeaderData(); | resolveLocalFileHeaderData(); | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
try { | try { | ||||
@@ -266,7 +334,7 @@ public class ZipFile { | |||||
* the central directory alone, but not the data that requires the | * the central directory alone, but not the data that requires the | ||||
* local file header or additional data to be read.</p> | * local file header or additional data to be read.</p> | ||||
*/ | */ | ||||
private void populateFromCentralDirectory() | |||||
private void populateFromCentralDirectory(boolean mustNotBeEmpty) | |||||
throws IOException { | throws IOException { | ||||
positionAtCentralDirectory(); | positionAtCentralDirectory(); | ||||
@@ -276,7 +344,7 @@ public class ZipFile { | |||||
archive.readFully(signatureBytes); | archive.readFully(signatureBytes); | ||||
long sig = ZipLong.getValue(signatureBytes); | long sig = ZipLong.getValue(signatureBytes); | ||||
final long cfhSig = ZipLong.getValue(ZipOutputStream.CFH_SIG); | final long cfhSig = ZipLong.getValue(ZipOutputStream.CFH_SIG); | ||||
if (sig != cfhSig) { | |||||
if (mustNotBeEmpty && sig != cfhSig) { | |||||
throw new IOException("central directory is empty, can't expand" | throw new IOException("central directory is empty, can't expand" | ||||
+ " archive."); | + " archive."); | ||||
} | } | ||||