diff --git a/src/main/org/apache/tools/ant/taskdefs/Expand.java b/src/main/org/apache/tools/ant/taskdefs/Expand.java
index a586556..a3a2745 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Expand.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Expand.java
@@ -69,6 +69,7 @@ public class Expand extends Task {
private boolean failOnEmptyArchive = false;
private boolean stripAbsolutePathSpec = false;
private boolean scanForUnicodeExtraFields = true;
+ private Boolean allowFilesToEscapeDest = null;
public static final String NATIVE_ENCODING = "native-encoding";
@@ -259,14 +260,17 @@ public class Expand extends Task {
boolean isDirectory, FileNameMapper mapper)
throws IOException {
- if (stripAbsolutePathSpec && entryName.length() > 0
+ final boolean entryNameStartsWithPathSpec = entryName.length() > 0
&& (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.size() > 0) {
String name = entryName.replace('/', File.separatorChar)
@@ -332,6 +336,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()) {
@@ -533,4 +543,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.9.12
+ */
+ 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.9.12
+ */
+ public Boolean getAllowFilesToEscapeDest() {
+ return allowFilesToEscapeDest;
+ }
+
}
--
2.7.4