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

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


The following commit(s) were added to refs/heads/1.22 by this push:
     new be953656b8 OAK-10462: 
o.a.j.o.plugins.version.VersionEditor#propertyAdded() may mistakenly assume an 
ongoing restore operation. (#1141)
be953656b8 is described below

commit be953656b8767a3faddc51d5195898dcba76db09
Author: mbaedke <manfred.bae...@gmail.com>
AuthorDate: Fri Nov 3 11:24:32 2023 +0100

    OAK-10462: o.a.j.o.plugins.version.VersionEditor#propertyAdded() may 
mistakenly assume an ongoing restore operation. (#1141)
    
    Improved heuristics to identify the sentinel node of a restore operation; 
added unit test.
---
 .../jackrabbit/oak/plugins/version/VersionEditor.java    | 16 +++++++++++++---
 .../apache/jackrabbit/oak/jcr/version/RestoreTest.java   |  9 +++++++++
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git 
a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionEditor.java
 
b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionEditor.java
index bd1a811c8f..42bf67189d 100644
--- 
a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionEditor.java
+++ 
b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionEditor.java
@@ -24,8 +24,11 @@ import javax.jcr.version.OnParentVersionAction;
 import org.apache.jackrabbit.JcrConstants;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Tree;
 import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
 import org.apache.jackrabbit.oak.plugins.tree.factories.TreeFactory;
+import org.apache.jackrabbit.oak.plugins.tree.impl.TreeProviderService;
 import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
 import org.apache.jackrabbit.oak.spi.commit.Editor;
 import org.apache.jackrabbit.oak.spi.lock.LockConstants;
@@ -35,6 +38,7 @@ import org.apache.jackrabbit.oak.spi.version.VersionConstants;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import static org.apache.jackrabbit.JcrConstants.MIX_VERSIONABLE;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.apache.jackrabbit.JcrConstants.JCR_BASEVERSION;
 import static org.apache.jackrabbit.JcrConstants.JCR_ISCHECKEDOUT;
@@ -108,9 +112,15 @@ class VersionEditor implements Editor {
                 && this.after.hasProperty(JcrConstants.JCR_VERSIONHISTORY)
                 && !this.after.hasProperty(JCR_ISCHECKEDOUT)
                 && !this.before.exists()) {
-            // sentinel node for restore
-            vMgr.restore(node, after.getValue(Type.REFERENCE), null);
-            return;
+            Tree tree = new 
TreeProviderService().createReadOnlyTree(this.node.getNodeState());
+            if (vMgr.getNodeTypeManager().isNodeType(
+                    TreeUtil.getPrimaryTypeName(tree), 
TreeUtil.getMixinTypeNames(tree), MIX_VERSIONABLE)) {
+                // OAK-10462: the node has mix:versionable, but not the 
mandatory property jcr:isCheckedOut,
+                // so it has to be sentinel node for a restore operation.
+                // Unfortunately, there is no API available to detect that.
+                vMgr.restore(node, after.getValue(Type.REFERENCE), null);
+                return;
+            }
         }
         if (!isReadOnly || getOPV(after) == OnParentVersionAction.IGNORE) {
             return;
diff --git 
a/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/version/RestoreTest.java 
b/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/version/RestoreTest.java
index 1cd138389f..5576b6b4d3 100644
--- 
a/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/version/RestoreTest.java
+++ 
b/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/version/RestoreTest.java
@@ -76,4 +76,13 @@ public class RestoreTest extends AbstractJCRTest {
         assertFalse("Restored node must not have jcr:frozenPrimaryType 
property",
                 child.hasProperty(JcrConstants.JCR_FROZENPRIMARYTYPE));
     }
+
+    //OAK-10462: a new node that looks remotely like a sentinel node of a 
restore operation may
+    //actually trigger a restore operation.
+    public void testCreateFakeSentinelNode() throws RepositoryException {
+        Node n = testRootNode.addNode(nodeName1, ntUnstructured);
+        n.setProperty(jcrVersionHistory, "");
+        n.setProperty(jcrBaseVersion, "");
+        superuser.save();
+    }
 }

Reply via email to