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(); + } }