File apache-ant-unzip-path.patch of Package ant-antlr.8804

Index: apache-ant-1.9.10/manual/Tasks/unzip.html
===================================================================
--- apache-ant-1.9.10.orig/manual/Tasks/unzip.html
+++ apache-ant-1.9.10/manual/Tasks/unzip.html
@@ -126,7 +126,7 @@ archive.</p>
       Note that this changes the entry's name before applying
       include/exclude patterns and before using the nested mappers (if
       any).  <em>since Ant 1.8.0</em></td>
-    <td valign="top" align="center">No, defaults to false</td>
+    <td valign="top" align="center">No, defaults to true</td>
   </tr>
   <tr>
     <td valign="top">scanForUnicodeExtraFields</td>
@@ -138,6 +138,15 @@ archive.</p>
       zip task page</a></td>
     <td align="center" valign="top">No, defaults to true</td>
   </tr>
+  <tr>
+    <td valign="top">allowFilesToEscapeDest</td>
+    <td valign="top">Whether to allow the extracted file or directory
+      to be outside of the dest directory.
+      <em>since Ant 1.9.12</em></td>
+    <td valign="top" align="center">No, defaults to false unless
+    stripAbsolutePathSpec is true and the entry's name starts with a leading
+    path spec.</td>
+  </tr>
 </table>
 <h3>Examples</h3>
 <pre>
Index: apache-ant-1.9.10/src/main/org/apache/tools/ant/taskdefs/Expand.java
===================================================================
--- apache-ant-1.9.10.orig/src/main/org/apache/tools/ant/taskdefs/Expand.java
+++ apache-ant-1.9.10/src/main/org/apache/tools/ant/taskdefs/Expand.java
@@ -67,8 +67,9 @@ public class Expand extends Task {
     private Union resources = new Union();
     private boolean resourcesSpecified = false;
     private boolean failOnEmptyArchive = false;
-    private boolean stripAbsolutePathSpec = false;
+    private boolean stripAbsolutePathSpec = true;
     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, true)) {
+            log("skipping " + entryName + " as its target " + f.getCanonicalPath()
+                + " is outside of " + dir.getCanonicalPath() + ".", Project.MSG_VERBOSE);
+	    return;
+        }
+
         try {
             if (!overwrite && f.exists()
                 && f.lastModified() >= entryDate.getTime()) {
@@ -533,4 +543,24 @@ 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;
+    }
+
 }
Index: apache-ant-1.9.10/src/main/org/apache/tools/ant/util/FileUtils.java
===================================================================
--- apache-ant-1.9.10.orig/src/main/org/apache/tools/ant/util/FileUtils.java
+++ apache-ant-1.9.10/src/main/org/apache/tools/ant/util/FileUtils.java
@@ -1191,6 +1191,36 @@ public class FileUtils {
     }
 
     /**
+     * Learn whether one path "leads" another.
+     *
+     * @param leading The leading path, must not be null, must be absolute.
+     * @param path The path to check, must not be null, must be absolute.
+     * @param resolveSymlinks whether symbolic links shall be resolved
+     * prior to comparing the paths.
+     * @return true if path starts with leading; false otherwise.
+     * @since Ant 1.9.13
+     * @throws IOException if resolveSymlinks is true and invoking
+     * getCanonicaPath on either argument throws an exception
+     */
+    public boolean isLeadingPath(File leading, File path, boolean resolveSymlinks)
+        throws IOException {
+        if (!resolveSymlinks) {
+            return isLeadingPath(leading, path);
+        }
+        String l = leading.getCanonicalPath();
+        String p = path.getCanonicalPath();
+        if (l.equals(p)) {
+            return true;
+        }
+        // ensure that l ends with a /
+        // so we never think /foo was a parent directory of /foobar
+        if (!l.endsWith(File.separator)) {
+            l += File.separator;
+        }
+        return p.startsWith(l);
+    }
+
+    /**
      * Constructs a <code>file:</code> URI that represents the
      * external form of the given pathname.
      *