You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by re...@apache.org on 2021/12/16 12:39:56 UTC

[jackrabbit-filevault] branch master updated: JCRVLT-575: handle symlinks in homeDir path (#188)

This is an automated email from the ASF dual-hosted git repository.

reschke pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jackrabbit-filevault.git


The following commit(s) were added to refs/heads/master by this push:
     new 6458a0a  JCRVLT-575: handle symlinks in homeDir path (#188)
6458a0a is described below

commit 6458a0aaced2cdd7d016acc1df0c02d5ebc28995
Author: Julian Reschke <re...@apache.org>
AuthorDate: Thu Dec 16 13:39:48 2021 +0100

    JCRVLT-575: handle symlinks in homeDir path (#188)
    
    * JCRVLT-575: handle symlinks in homeDir path
    
    * JCRVLT-575: log and abort when homeDir is present, but not a directory
    
    * JCRVLT-575: add minimal test coverage
---
 .../registry/impl/FSInstallStateCache.java         | 23 +++++++++++++--
 .../registry/impl/FSPackageRegistryTest.java       | 33 +++++++++++++++++++++-
 2 files changed, 52 insertions(+), 4 deletions(-)

diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSInstallStateCache.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSInstallStateCache.java
index a68de14..51f5f0e 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSInstallStateCache.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSInstallStateCache.java
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.vault.packaging.registry.impl;
 
 import java.io.IOException;
 import java.io.UncheckedIOException;
+import java.nio.file.FileVisitOption;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.AbstractMap;
@@ -30,6 +31,8 @@ import java.util.stream.Stream;
 
 import org.apache.jackrabbit.vault.packaging.PackageId;
 import org.jetbrains.annotations.NotNull;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Persisted cache of all {@link FSInstallState} objects for all packages in a registry.
@@ -39,6 +42,8 @@ import org.jetbrains.annotations.NotNull;
  */
 class FSInstallStateCache extends AbstractMap<PackageId, FSInstallState> {
 
+    private static final Logger log = LoggerFactory.getLogger(FSInstallStateCache.class);
+
     /**
      * Extension for metadata files
      */
@@ -53,10 +58,20 @@ class FSInstallStateCache extends AbstractMap<PackageId, FSInstallState> {
     private Map<Path, PackageId> pathIdMapping = new ConcurrentHashMap<>();
 
     private final Path homeDir;
-    
+
     public FSInstallStateCache(Path homeDir) throws IOException {
         this.homeDir = homeDir;
-        Files.createDirectories(homeDir);
+        log.debug("checking for presence of {} - exists {} - isDirectory {}", homeDir, Files.exists(homeDir), Files.isDirectory(homeDir));
+        if (!Files.exists(homeDir)) {
+            Path created = Files.createDirectories(homeDir);
+            log.debug("Created {}", created);
+        } else {
+            if (!Files.isDirectory(homeDir)) {
+                String message = homeDir + " exists, but is not a directory - aborting";
+                log.error(message);
+                throw new IOException(message);
+            }
+        }
     }
 
     /**
@@ -68,12 +83,14 @@ class FSInstallStateCache extends AbstractMap<PackageId, FSInstallState> {
         Map<Path, PackageId> idMapping = new HashMap<>();
 
         // recursively find meta file
-        try (Stream<Path> stream = Files.walk(homeDir, 10)) {
+        log.debug("loading state from home directory {}", homeDir);
+        try (Stream<Path> stream = Files.walk(homeDir, 10, FileVisitOption.FOLLOW_LINKS)) {
             stream.filter(Files::isRegularFile).filter(p -> p.toString().endsWith(META_EXTENSION)).forEach(
                 p -> {
                     FSInstallState state;
                     try {
                         state = FSInstallState.fromFile(p);
+                        log.debug("loaded state from {}", p);
                     } catch (IOException e) {
                         throw new UncheckedIOException(e);
                     }
diff --git a/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSPackageRegistryTest.java b/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSPackageRegistryTest.java
index 880d326..12ede04 100644
--- a/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSPackageRegistryTest.java
+++ b/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/registry/impl/FSPackageRegistryTest.java
@@ -19,11 +19,14 @@ package org.apache.jackrabbit.vault.packaging.registry.impl;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.file.FileSystemException;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
 import java.util.Collections;
 import java.util.HashMap;
@@ -47,7 +50,7 @@ public class FSPackageRegistryTest {
     public TemporaryFolder tmpFolder = new TemporaryFolder();
 
     private static final PackageId TEST_PACKAGE_ID = new PackageId("test", "test-package-with-etc", "1.0");
-    
+
     private void copyResourceStreamToFile(Path targetFile, String name) throws IOException {
         try (InputStream in = getClass().getResourceAsStream(name)) {
             Files.copy(in, targetFile, StandardCopyOption.REPLACE_EXISTING);
@@ -62,6 +65,34 @@ public class FSPackageRegistryTest {
     }
 
     @Test
+    public void testFailHomeDirIsFile() throws IOException {
+        Path tmpDir = tmpFolder.newFolder().toPath();
+        Path file = Paths.get(tmpDir.toFile().getPath(), "file");
+        Files.write(file, "EMPTY".getBytes());
+        try {
+            createRegistryWithDefaultConstructor(file);
+            fail("registry creation should fail when homeDir is a file, not a directory");
+        } catch(IOException expected) {
+            // ok
+        }
+    }
+
+    @Test
+    public void testHomeDirIsSymlink() throws IOException {
+        Path tmpDir = tmpFolder.newFolder().toPath();
+        Path path = Paths.get(tmpDir.toFile().getPath(), "path");
+        Files.createDirectories(path);
+        Path link = Paths.get(tmpDir.toFile().getPath(), "link");
+        try {
+            Files.createSymbolicLink(link, path);
+            createRegistryWithDefaultConstructor(link);
+        }
+        catch (FileSystemException tolerated) {
+            // symlink creation apparently unsupported
+        }
+    }
+
+    @Test
     public void testRegisterAndRemove() throws IOException, PackageExistsException, NoSuchPackageException {
         FSPackageRegistry registry = createRegistryWithDefaultConstructor(tmpFolder.newFolder().toPath());
         try (InputStream in = getClass().getResourceAsStream("test-package.zip")) {