Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 51 additions & 13 deletions test/jdk/tools/jar/JarExtractTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand All @@ -26,8 +26,11 @@
import java.io.IOException;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
Expand Down Expand Up @@ -65,12 +68,12 @@ public class JarExtractTest {
private static final byte[] FILE_CONTENT = "Hello world!!!".getBytes(StandardCharsets.UTF_8);
// the jar that will get extracted in the tests
private Path testJarPath;
private static Collection<Path> filesToDelete = new ArrayList<>();
private static final Collection<Path> filesToDelete = new ArrayList<>();

@BeforeEach
public void createTestJar() throws Exception {
final String tmpDir = Files.createTempDirectory("8173970-").toString();
testJarPath = Path.of(tmpDir, "8173970-test.jar");
final Path tmpDir = Files.createTempDirectory(Path.of("."), "8173970-");
testJarPath = tmpDir.resolve("8173970-test.jar");
final JarBuilder builder = new JarBuilder(testJarPath.toString());
// d1
// |--- d2
Expand Down Expand Up @@ -273,22 +276,34 @@ public void testExtractToNonDirectory() throws Exception {
* Tests that extracting a jar using {@code -P} flag and without any explicit destination
* directory works correctly if the jar contains entries with leading slashes and/or {@code ..}
* parts preserved.
* The test creates a JAR file with an entry which has a leading slash in its name and
* another entry that has ".." in its entry name. jar tool is then used to extract that JAR file
* with the "-P" option which is to preserve leading '/' (absolute path)
* and ".." (parent directory) components when extracting those entries. This test then verifies
* that after successfully extracting that JAR file, these entries are present at the expected
* paths on the filesystem.
*/
@Test
public void testExtractNoDestDirWithPFlag() throws Exception {
// run this test only on those systems where "/tmp" directory is available and we
// can write to it
// This test requires that the entry in the JAR file have a leading slash, which
// upon extraction of that JAR file will correspond to a filesystem path. Not all
// environments may have a writable location that starts with "/". "/tmp" is one
// commonly available filesystem directory which is usually writable. Here we check the
// presence of "/tmp" directory and verify that files can be created in that directory.
// If we can't, then we skip this test.
Assumptions.assumeTrue(Files.isDirectory(Path.of("/tmp")),
"skipping test, since /tmp isn't a directory");
// try and write into "/tmp"
final Path tmpDir;
final Path tempTestDir;
try {
tmpDir = Files.createTempDirectory(Path.of("/tmp"), "8173970-").toAbsolutePath();
// create a test specific directory in "/tmp" directory
tempTestDir = Files.createTempDirectory(Path.of("/tmp"), "8173970-");
} catch (IOException ioe) {
Assumptions.abort("skipping test, since /tmp cannot be written to: " + ioe);
// The above Assumptions.abort(...) call makes this "return" unreachable, but we keep
// the "return" for code clarity.
return;
}
final String leadingSlashEntryName = tmpDir.toString() + "/foo/f1.txt";
final String leadingSlashEntryName = tempTestDir.toString() + "/foo/f1.txt";
// create a jar which has leading slash (/) and dot-dot (..) preserved in entry names
final Path jarPath = createJarWithPFlagSemantics(leadingSlashEntryName);
final List<String[]> cmdArgs = new ArrayList<>();
Expand All @@ -315,8 +330,9 @@ public void testExtractNoDestDirWithPFlag() throws Exception {
"Unexpected content in file " + f2);
}
} finally {
// clean up the file that might have been extracted into "/tmp/...." directory
Files.deleteIfExists(Path.of(leadingSlashEntryName));
// clean up the temp directory created by this test under "/tmp/...." directory
System.err.println("Deleting directory: " + tempTestDir);
deleteRecursively(tempTestDir);
}
}

Expand Down Expand Up @@ -514,4 +530,26 @@ private static Path createJarWithPFlagSemantics(String leadingSlashEntryName)
private static void printJarCommand(final String[] cmdArgs) {
System.out.println("Running 'jar " + String.join(" ", cmdArgs) + "'");
}
}

private static void deleteRecursively(final Path dir) throws IOException {
Files.walkFileTree(dir, new FileVisitor<>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
return FileVisitResult.CONTINUE;
}
@Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
Files.delete(file); // delete the file
return FileVisitResult.CONTINUE;
}
@Override public FileVisitResult visitFileFailed(Path file, IOException exc) {
return FileVisitResult.CONTINUE;
}
@Override public FileVisitResult postVisitDirectory(Path dir, IOException exc)
throws IOException {
Files.delete(dir); // delete the (empty) directory
return FileVisitResult.CONTINUE;
}
});
}
}