mirror of
https://github.com/spring-projects/spring-boot.git
synced 2026-09-17 12:09:16 +00:00
Merge branch '4.0.x'
Closes gh-50510
This commit is contained in:
+12
-6
@@ -26,6 +26,7 @@ import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.BasicFileAttributeView;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.nio.file.attribute.FileTime;
|
||||
@@ -57,6 +58,7 @@ import org.springframework.util.StringUtils;
|
||||
* The {@code 'extract'} tools command.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Dongliang Xie
|
||||
*/
|
||||
class ExtractCommand extends Command {
|
||||
|
||||
@@ -363,14 +365,18 @@ class ExtractCommand extends Command {
|
||||
}
|
||||
|
||||
private static File assertFileIsContainedInDirectory(File directory, File file, String name) throws IOException {
|
||||
String canonicalOutputPath = directory.getCanonicalPath() + File.separator;
|
||||
String canonicalEntryPath = file.getCanonicalPath();
|
||||
Assert.state(canonicalEntryPath.startsWith(canonicalOutputPath),
|
||||
Path canonicalOutputPath = directory.getCanonicalFile().toPath();
|
||||
Path canonicalEntryPath = file.getCanonicalFile().toPath();
|
||||
Assert.state(isFileContainedInDirectory(canonicalOutputPath, canonicalEntryPath),
|
||||
() -> "Entry '%s' would be written to '%s'. This is outside the output location of '%s'. Verify the contents of your archive."
|
||||
.formatted(name, canonicalEntryPath, canonicalOutputPath));
|
||||
return file;
|
||||
}
|
||||
|
||||
private static boolean isFileContainedInDirectory(Path directory, Path file) {
|
||||
return !file.equals(directory) && file.startsWith(directory);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
private interface EntryNameTransformer {
|
||||
|
||||
@@ -515,9 +521,9 @@ class ExtractCommand extends Command {
|
||||
}
|
||||
|
||||
private File assertLayerDirectoryLocation(File layerDirectory, String layerName) throws IOException {
|
||||
String canonicalOutputPath = this.directory.getCanonicalPath() + File.separator;
|
||||
String canonicalLayerPath = layerDirectory.getCanonicalPath();
|
||||
Assert.state(canonicalLayerPath.startsWith(canonicalOutputPath),
|
||||
Path canonicalOutputPath = this.directory.getCanonicalFile().toPath();
|
||||
Path canonicalLayerPath = layerDirectory.getCanonicalFile().toPath();
|
||||
Assert.state(isFileContainedInDirectory(canonicalOutputPath, canonicalLayerPath),
|
||||
() -> "Layer '%s' would be written to '%s'. This is outside the output location of '%s'. Verify the contents of your archive."
|
||||
.formatted(layerName, canonicalLayerPath, canonicalOutputPath));
|
||||
return layerDirectory;
|
||||
|
||||
+35
@@ -20,11 +20,13 @@ import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.BasicFileAttributeView;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.jar.Manifest;
|
||||
@@ -45,6 +47,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
* Tests for {@link ExtractCommand}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Dongliang Xie
|
||||
*/
|
||||
class ExtractCommandTests extends AbstractJarModeTests {
|
||||
|
||||
@@ -370,6 +373,38 @@ class ExtractCommandTests extends AbstractJarModeTests {
|
||||
.doesNotContain("test/spring-boot-loader/org/springframework/boot/loader/launch/JarLauncher.class");
|
||||
}
|
||||
|
||||
@Test
|
||||
void extractWhenDestinationIsFileSystemRoot() throws IOException {
|
||||
Path layerDirectory = ExtractCommandTests.this.tempDir.toPath()
|
||||
.resolve("root-output")
|
||||
.resolve("dependencies")
|
||||
.toAbsolutePath()
|
||||
.normalize();
|
||||
Path outputRoot = layerDirectory.getRoot();
|
||||
String layerName = outputRoot.relativize(layerDirectory).toString().replace(File.separatorChar, '/');
|
||||
Layers layers = new Layers() {
|
||||
|
||||
@Override
|
||||
public Iterator<String> iterator() {
|
||||
return List.of(layerName).iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLayer(String entryName) {
|
||||
return layerName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getApplicationLayerName() {
|
||||
return layerName;
|
||||
}
|
||||
|
||||
};
|
||||
runCommand((context) -> new ExtractCommand(context, layers), ExtractCommandTests.this.archive,
|
||||
"--destination", outputRoot.toString(), "--force", "--launcher", "--layers");
|
||||
assertThat(layerDirectory.resolve("BOOT-INF/lib/dependency-1.jar")).exists();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user