Repository: GoogleContainerTools/jib
File: jib-plugins-common/src/main/java/com/google/cloud/tools/jib/plugins/common/JavaContainerBuilderHelper.java (Java)

Code before:
        .map(pattern -> FileSystems.getDefault().getPathMatcher("glob:" + pattern))
        .map(pathMatcher -> (Predicate<Path>) (path -> pathMatcher.matches(path)))
        .reduce((matches1, matches2) -> matches1.or(matches2))
        .ifPresent(walker::filter);
    walker.walk(
        localPath -> {
          AbsoluteUnixPath pathOnContainer =
              targetDirectory.resolve(sourceDirectory.relativize(localPath));
          Instant modificationTime = modificationTimeProvider.get(localPath, pathOnContainer);
          FilePermissions permissions = extraDirectoryPermissions.get(pathOnContainer.toString());
          if (permissions == null) {
            // Check for matching globs
            Path containerPath = Paths.get(pathOnContainer.toString());
            for (Map.Entry<PathMatcher, FilePermissions> entry : pathMatchers.entrySet()) {
              if (entry.getKey().matches(containerPath)) {
                builder.addEntry(localPath, pathOnContainer, entry.getValue(), modificationTime);
                return;
              }
            }

            // Add with default permissions
            builder.addEntry(localPath, pathOnContainer, modificationTime);
          } else {
            // Add with explicit permissions
            builder.addEntry(localPath, pathOnContainer, permissions, modificationTime);
          }
        });
    return builder.build();
  }

  /**
   * Constructs a new {@link JibContainerBuilder} for a WAR project.
   *
   * @param javaContainerBuilder Java container builder to start with
   * @param explodedWar the exploded WAR directory
   * @param projectArtifactFilename the file names of project artifacts for project dependencies
   * @return {@link JibContainerBuilder} containing the layers for the exploded WAR
   * @throws IOException if adding layer contents fails
   */
  public static JibContainerBuilder fromExplodedWar(
      JavaContainerBuilder javaContainerBuilder,
      Path explodedWar,
      Set<String> projectArtifactFilename)
      throws IOException {
    Path webInfLib = explodedWar.resolve("WEB-INF/lib");
    Path webInfClasses = explodedWar.resolve("WEB-INF/classes");
    Predicate<Path> isDependency = path -> path.startsWith(webInfLib);
    Predicate<Path> isClassFile =
        // Don't use Path.endsWith(), since Path works on path elements.
        path -> path.startsWith(webInfClasses) && path.getFileName().toString().endsWith(".class");
    Predicate<Path> isResource = isDependency.or(isClassFile).negate();

Review comment (security):
```suggestion
          } 
            // Add with explicit permissions
            builder.addEntry(localPath, pathOnContainer, permissions, modificationTime);
```

Code after:
    // add an inclusion filter
    includes
        .stream()
        .map(pattern -> FileSystems.getDefault().getPathMatcher("glob:" + pattern))
        .map(pathMatcher -> (Predicate<Path>) (path -> pathMatcher.matches(path)))
        .reduce((matches1, matches2) -> matches1.or(matches2))
        .ifPresent(walker::filter);
    // walk the source tree and add layer entries
    walker.walk(
        localPath -> {
          AbsoluteUnixPath pathOnContainer =
              targetDirectory.resolve(sourceDirectory.relativize(localPath));
          Instant modificationTime = modificationTimeProvider.get(localPath, pathOnContainer);
          Optional<FilePermissions> permissions =
              determinePermissions(
                  pathOnContainer, extraDirectoryPermissions, permissionsPathMatchers);
          if (permissions.isPresent()) {
            builder.addEntry(localPath, pathOnContainer, permissions.get(), modificationTime);
          } else {
            builder.addEntry(localPath, pathOnContainer, modificationTime);
          }
        });
    return builder.build();
  }

  private static Optional<FilePermissions> determinePermissions(
      AbsoluteUnixPath path,
      Map<String, FilePermissions> extraDirectoryPermissions,
      Map<PathMatcher, FilePermissions> permissionsPathMatchers) {
    // The check is only for optimization. (`permissionsPathMatchers` is constructed from the map.)
    FilePermissions permissions = extraDirectoryPermissions.get(path.toString());
    if (permissions != null) {
      return Optional.of(permissions);
    }

    // Check for matching globs
    for (Map.Entry<PathMatcher, FilePermissions> entry : permissionsPathMatchers.entrySet()) {
      if (entry.getKey().matches(Paths.get(path.toString()))) {
        return Optional.of(entry.getValue());
      }
    }
    return Optional.empty();
  }

  /**
   * Constructs a new {@link JibContainerBuilder} for a WAR project.
   *
   * @param javaContainerBuilder Java container builder to start with
   * @param explodedWar the exploded WAR directory
   * @param projectArtifactFilename the file names of project artifacts for project dependencies
   * @return {@link JibContainerBuilder} containing the layers for the exploded WAR