2424import java .nio .file .StandardOpenOption ;
2525import java .util .StringJoiner ;
2626import java .util .zip .GZIPInputStream ;
27+ import java .util .zip .ZipEntry ;
2728import java .util .zip .ZipFile ;
2829import org .apache .baremaps .workflow .Task ;
2930import org .apache .baremaps .workflow .WorkflowContext ;
@@ -154,22 +155,26 @@ protected static void decompressTarBz2(Path source, Path target) throws IOExcept
154155 }
155156 }
156157
157- private static void decompressTar (Path target , TarArchiveInputStream tarInputStream )
158- throws IOException {
158+ public static void decompressTar (Path target , TarArchiveInputStream tarInputStream ) throws IOException {
159159 TarArchiveEntry entry ;
160160 while ((entry = tarInputStream .getNextEntry ()) != null ) {
161- var path = target .resolve (entry .getName ());
162- if (entry .isDirectory ()) {
163- Files .createDirectories (path );
164- } else {
165- Files .createDirectories (path .getParent ());
166- Files .write (path , new byte [] {},
167- StandardOpenOption .CREATE ,
168- StandardOpenOption .TRUNCATE_EXISTING );
169- try (BufferedOutputStream outputStream =
170- new BufferedOutputStream (Files .newOutputStream (path ))) {
171- tarInputStream .transferTo (outputStream );
161+ Path resolvedPath = target .resolve (entry .getName ()).normalize ();
162+ File file = resolvedPath .toFile ();
163+
164+ String canonicalDestinationPath = file .getCanonicalPath ();
165+ String canonicalTargetPath = target .toFile ().getCanonicalPath ();
166+
167+ if (canonicalDestinationPath .startsWith (canonicalTargetPath )) {
168+ if (entry .isDirectory ()) {
169+ Files .createDirectories (resolvedPath );
170+ } else {
171+ Files .createDirectories (resolvedPath .getParent ());
172+ try (BufferedOutputStream outputStream = new BufferedOutputStream (Files .newOutputStream (resolvedPath , StandardOpenOption .CREATE , StandardOpenOption .TRUNCATE_EXISTING ))) {
173+ tarInputStream .transferTo (outputStream );
174+ }
172175 }
176+ } else {
177+ throw new IOException ("Entry is outside of the target directory" );
173178 }
174179 }
175180 }
@@ -183,23 +188,28 @@ private static void decompressTar(Path target, TarArchiveInputStream tarInputStr
183188 */
184189 @ SuppressWarnings ("squid:S5042" )
185190 protected static void decompressZip (Path source , Path target ) throws IOException {
186- Files .createDirectories (target );
187- try (var zipFile = new ZipFile (source .toFile ())) {
191+ try (ZipFile zipFile = new ZipFile (source .toFile ())) {
188192 var entries = zipFile .entries ();
189193 while (entries .hasMoreElements ()) {
190- var entry = entries .nextElement ();
191- var path = target .resolve (entry .getName ());
192- if (entry .isDirectory ()) {
193- Files .createDirectories (path );
194- } else {
195- Files .createDirectories (path .getParent ());
196- Files .write (path , new byte [] {},
197- StandardOpenOption .CREATE ,
198- StandardOpenOption .TRUNCATE_EXISTING );
199- try (var input = new BufferedInputStream (zipFile .getInputStream (entry ));
200- var output = new BufferedOutputStream (new FileOutputStream (path .toFile ()))) {
201- input .transferTo (output );
194+ ZipEntry entry = entries .nextElement ();
195+ Path resolvedPath = target .resolve (entry .getName ()).normalize ();
196+ File file = resolvedPath .toFile ();
197+
198+ String canonicalDestinationPath = file .getCanonicalPath ();
199+ String canonicalTargetPath = target .toFile ().getCanonicalPath ();
200+
201+ if (canonicalDestinationPath .startsWith (canonicalTargetPath )) {
202+ if (entry .isDirectory ()) {
203+ Files .createDirectories (resolvedPath );
204+ } else {
205+ Files .createDirectories (resolvedPath .getParent ());
206+ try (BufferedInputStream input = new BufferedInputStream (zipFile .getInputStream (entry ));
207+ BufferedOutputStream output = new BufferedOutputStream (new FileOutputStream (file ))) {
208+ input .transferTo (output );
209+ }
202210 }
211+ } else {
212+ throw new IOException ("Entry is outside of the target directory" );
203213 }
204214 }
205215 }
0 commit comments