@@ -69,6 +69,7 @@ public class Expand extends Task {
6969 private boolean failOnEmptyArchive = false ;
7070 private boolean stripAbsolutePathSpec = false ;
7171 private boolean scanForUnicodeExtraFields = true ;
72+ private Boolean allowFilesToEscapeDest = null ;
7273
7374 public static final String NATIVE_ENCODING = "native-encoding" ;
7475
@@ -259,14 +260,17 @@ protected void extractFile(FileUtils fileUtils, File srcF, File dir,
259260 boolean isDirectory , FileNameMapper mapper )
260261 throws IOException {
261262
262- if ( stripAbsolutePathSpec && entryName .length () > 0
263+ final boolean entryNameStartsWithPathSpec = entryName .length () > 0
263264 && (entryName .charAt (0 ) == File .separatorChar
264265 || entryName .charAt (0 ) == '/'
265- || entryName .charAt (0 ) == '\\' )) {
266+ || entryName .charAt (0 ) == '\\' );
267+ if (stripAbsolutePathSpec && entryNameStartsWithPathSpec ) {
266268 log ("stripped absolute path spec from " + entryName ,
267269 Project .MSG_VERBOSE );
268270 entryName = entryName .substring (1 );
269271 }
272+ boolean allowedOutsideOfDest = Boolean .TRUE == getAllowFilesToEscapeDest ()
273+ || null == getAllowFilesToEscapeDest () && !stripAbsolutePathSpec && entryNameStartsWithPathSpec ;
270274
271275 if (patternsets != null && patternsets .size () > 0 ) {
272276 String name = entryName .replace ('/' , File .separatorChar )
@@ -332,6 +336,12 @@ protected void extractFile(FileUtils fileUtils, File srcF, File dir,
332336 mappedNames = new String [] {entryName };
333337 }
334338 File f = fileUtils .resolveFile (dir , mappedNames [0 ]);
339+ if (!allowedOutsideOfDest && !fileUtils .isLeadingPath (dir , f )) {
340+ log ("skipping " + entryName + " as its target " + f + " is outside of "
341+ + dir + "." , Project .MSG_VERBOSE );
342+ return ;
343+ }
344+
335345 try {
336346 if (!overwrite && f .exists ()
337347 && f .lastModified () >= entryDate .getTime ()) {
@@ -533,4 +543,25 @@ public boolean getScanForUnicodeExtraFields() {
533543 return scanForUnicodeExtraFields ;
534544 }
535545
546+ /**
547+ * Whether to allow the extracted file or directory to be outside of the dest directory.
548+ *
549+ * @param b the flag
550+ * @since Ant 1.9.12
551+ */
552+ public void setAllowFilesToEscapeDest (boolean b ) {
553+ allowFilesToEscapeDest = b ;
554+ }
555+
556+ /**
557+ * Whether to allow the extracted file or directory to be outside of the dest directory.
558+ *
559+ * @return {@code null} if the flag hasn't been set explicitly,
560+ * otherwise the value set by the user.
561+ * @since Ant 1.9.12
562+ */
563+ public Boolean getAllowFilesToEscapeDest () {
564+ return allowFilesToEscapeDest ;
565+ }
566+
536567}
0 commit comments