public void extract()

in appengine-plugins-core/src/main/java/com/google/cloud/tools/managedcloudsdk/install/ZipExtractorProvider.java [50:99]


  public void extract(Path archive, Path destination, ProgressListener progressListener)
      throws IOException {

    progressListener.start(
        "Extracting archive: " + archive.getFileName(), ProgressListener.UNKNOWN);

    String canonicalDestination = destination.toFile().getCanonicalPath();

    // Use ZipFile instead of ZipArchiveInputStream so that we can obtain file permissions
    // on unix-like systems via getUnixMode(). ZipArchiveInputStream doesn't have access to
    // all the zip file data and will return "0" for any call to getUnixMode().
    try (ZipFile zipFile = new ZipFile(archive.toFile())) {
      // TextProgressBar progressBar = textBarFactory.newProgressBar(messageListener, count);
      Enumeration<ZipArchiveEntry> zipEntries = zipFile.getEntries();
      while (zipEntries.hasMoreElements()) {
        ZipArchiveEntry entry = zipEntries.nextElement();
        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 (!Files.exists(entryTarget.getParent())) {
            Files.createDirectories(entryTarget.getParent());
          }
          try (OutputStream out = new BufferedOutputStream(Files.newOutputStream(entryTarget))) {
            try (InputStream in = zipFile.getInputStream(entry)) {
              IOUtils.copy(in, out);
              PosixFileAttributeView attributeView =
                  Files.getFileAttributeView(entryTarget, PosixFileAttributeView.class);
              if (attributeView != null) {
                attributeView.setPermissions(
                    PosixUtil.getPosixFilePermissions(entry.getUnixMode()));
              }
            }
          }
        }
      }
    }
    progressListener.done();
  }