in appengine-plugins-core/src/main/java/com/google/cloud/tools/managedcloudsdk/install/TarGzExtractorProvider.java [47:92]
public void extract(Path archive, Path destination, ProgressListener progressListener)
throws IOException {
progressListener.start(
"Extracting archive: " + archive.getFileName(), ProgressListener.UNKNOWN);
String canonicalDestination = destination.toFile().getCanonicalPath();
GzipCompressorInputStream gzipIn = new GzipCompressorInputStream(Files.newInputStream(archive));
try (TarArchiveInputStream in = new TarArchiveInputStream(gzipIn)) {
TarArchiveEntry entry;
while ((entry = in.getNextTarEntry()) != null) {
Path entryTarget = destination.resolve(entry.getName());
String canonicalTarget = entryTarget.toFile().getCanonicalPath();
if (!canonicalTarget.startsWith(canonicalDestination + File.separator)) {
throw new IOException("Blocked unzipping files outside destination: " + entry.getName());
}
progressListener.update(1);
logger.fine(entryTarget.toString());
if (entry.isDirectory()) {
if (!Files.exists(entryTarget)) {
Files.createDirectories(entryTarget);
}
} else if (entry.isFile()) {
if (!Files.exists(entryTarget.getParent())) {
Files.createDirectories(entryTarget.getParent());
}
try (OutputStream out = new BufferedOutputStream(Files.newOutputStream(entryTarget))) {
IOUtils.copy(in, out);
PosixFileAttributeView attributeView =
Files.getFileAttributeView(entryTarget, PosixFileAttributeView.class);
if (attributeView != null) {
attributeView.setPermissions(PosixUtil.getPosixFilePermissions(entry.getMode()));
}
}
} else {
// we don't know what kind of entry this is (we only process directories and files).
logger.warning("Skipping entry (unknown type): " + entry.getName());
}
}
progressListener.done();
}
}