Browse Source

Merge branch '1.9.x'

master
Stefan Bodewig 7 years ago
parent
commit
ae5a3e0ea3
5 changed files with 92 additions and 2 deletions
  1. +13
    -0
      WHATSNEW
  2. +33
    -2
      src/main/org/apache/tools/ant/taskdefs/Expand.java
  3. +46
    -0
      src/tests/antunit/taskdefs/unzip-test.xml
  4. BIN
      src/tests/antunit/taskdefs/zip/direscape-absolute.zip
  5. BIN
      src/tests/antunit/taskdefs/zip/direscape.zip

+ 13
- 0
WHATSNEW View File

@@ -1,6 +1,19 @@
Changes from Ant 1.10.3 TO Ant 1.10.4
=====================================

Changes that could break older environments:
-------------------------------------------

* <unzip>, <unjar> and <untar> will no longer extract entries whose
names would make the created files be placed outside of the
destination directory anymore by default. A new attribute
allowFilesToEscapeDest can be used to override the behavior.
Another special case is when stripAbsolutePathSpec is false (which
still is the default) and the entry's name starts with a
(back)slash and allowFilesToEscapeDest hasn't been specified
explicitly, in this case the file may be created outside of the
dest directory as well.

Fixed bugs:
-----------



+ 33
- 2
src/main/org/apache/tools/ant/taskdefs/Expand.java View File

@@ -77,6 +77,7 @@ public class Expand extends Task {
private boolean failOnEmptyArchive = false;
private boolean stripAbsolutePathSpec = false;
private boolean scanForUnicodeExtraFields = true;
private Boolean allowFilesToEscapeDest = null;

private String encoding;

@@ -256,14 +257,17 @@ public class Expand extends Task {
boolean isDirectory, FileNameMapper mapper)
throws IOException {

if (stripAbsolutePathSpec && !entryName.isEmpty()
final boolean entryNameStartsWithPathSpec = !entryName.isEmpty()
&& (entryName.charAt(0) == File.separatorChar
|| entryName.charAt(0) == '/'
|| entryName.charAt(0) == '\\')) {
|| entryName.charAt(0) == '\\');
if (stripAbsolutePathSpec && entryNameStartsWithPathSpec) {
log("stripped absolute path spec from " + entryName,
Project.MSG_VERBOSE);
entryName = entryName.substring(1);
}
boolean allowedOutsideOfDest = Boolean.TRUE == getAllowFilesToEscapeDest()
|| null == getAllowFilesToEscapeDest() && !stripAbsolutePathSpec && entryNameStartsWithPathSpec;

if (patternsets != null && !patternsets.isEmpty()) {
String name = entryName.replace('/', File.separatorChar)
@@ -328,6 +332,12 @@ public class Expand extends Task {
mappedNames = new String[] {entryName};
}
File f = fileUtils.resolveFile(dir, mappedNames[0]);
if (!allowedOutsideOfDest && !fileUtils.isLeadingPath(dir, f)) {
log("skipping " + entryName + " as its target " + f + " is outside of "
+ dir + ".", Project.MSG_VERBOSE);
return;
}

try {
if (!overwrite && f.exists()
&& f.lastModified() >= entryDate.getTime()) {
@@ -520,4 +530,25 @@ public class Expand extends Task {
return scanForUnicodeExtraFields;
}

/**
* Whether to allow the extracted file or directory to be outside of the dest directory.
*
* @param b the flag
* @since Ant 1.10.4
*/
public void setAllowFilesToEscapeDest(boolean b) {
allowFilesToEscapeDest = b;
}

/**
* Whether to allow the extracted file or directory to be outside of the dest directory.
*
* @return {@code null} if the flag hasn't been set explicitly,
* otherwise the value set by the user.
* @since Ant 1.10.4
*/
public Boolean getAllowFilesToEscapeDest() {
return allowFilesToEscapeDest;
}

}

+ 46
- 0
src/tests/antunit/taskdefs/unzip-test.xml View File

@@ -24,6 +24,10 @@
<mkdir dir="${output}" />
</target>

<target name="tearDown" depends="antunit-base.tearDown">
<delete dir="/tmp/testdir"/>
</target>

<target name="testFailureOnBrokenCentralDirectoryStructure">
<au:expectfailure
expectedmessage="central directory is empty, can't expand corrupt archive.">
@@ -67,4 +71,46 @@
<!-- failed on Windows and other OSes with implicit file locking -->
<au:assertFileDoesntExist file="${input}/test.zip"/>
</target>

<target name="testEntriesDontEscapeDestByDefault">
<mkdir dir="${input}/"/>
<mkdir dir="${output}/"/>
<unzip src="zip/direscape.zip" dest="${output}"/>
<au:assertFileDoesntExist file="${input}/a"/>
</target>

<target name="testEntriesCanEscapeDestIfRequested">
<mkdir dir="${input}/"/>
<mkdir dir="${output}/"/>
<unzip src="zip/direscape.zip" dest="${output}" allowFilesToEscapeDest="true"/>
<au:assertFileExists file="${input}/a"/>
</target>

<target name="-can-write-to-tmp?">
<mkdir dir="${input}"/>
<echo file="${input}/A.java"><![CDATA[
public class A {
public static void main(String[] args) {
new java.io.File("/tmp/testdir/").mkdirs();
}
}
]]></echo>
<mkdir dir="${output}"/>
<javac srcdir="${input}" destdir="${output}"/>
<java classname="A" classpath="${output}"/>
<available property="can-write-to-tmp!" file="/tmp/testdir/"/>
</target>

<target name="testEntriesCanEscapeDestViaAbsolutePathByDefault"
depends="-can-write-to-tmp?" if="can-write-to-tmp!">
<unzip src="zip/direscape-absolute.zip" dest="${output}"/>
<au:assertFileExists file="/tmp/testdir/a"/>
</target>

<target name="testEntriesDontEscapeDestViaAbsolutePathIfProhibited"
depends="-can-write-to-tmp?" if="can-write-to-tmp!">
<unzip src="zip/direscape-absolute.zip" dest="${output}"
allowFilesToEscapeDest="false"/>
<au:assertFileDoesntExist file="/tmp/testdir/a"/>
</target>
</project>

BIN
src/tests/antunit/taskdefs/zip/direscape-absolute.zip View File


BIN
src/tests/antunit/taskdefs/zip/direscape.zip View File


Loading…
Cancel
Save