This is an automated email from the ASF dual-hosted git repository. baedke pushed a commit to branch issue/oak-10621 in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git
The following commit(s) were added to refs/heads/issue/oak-10621 by this push: new d816705e8d OAK-10621: o.a.j.o.namepath.JcrPathParser does not accept indexed expanded names. d816705e8d is described below commit d816705e8df4af771001c95632780700b4fc1d01 Author: Manfred Baedke <manfred.bae...@gmail.com> AuthorDate: Thu Jan 25 12:45:04 2024 +0100 OAK-10621: o.a.j.o.namepath.JcrPathParser does not accept indexed expanded names. Fixed, added unit tests. --- .../jackrabbit/oak/namepath/JcrPathParser.java | 22 ++++---- .../jackrabbit/oak/namepath/PathParserTest.java | 58 ++++++++++++++++------ 2 files changed, 56 insertions(+), 24 deletions(-) diff --git a/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/namepath/JcrPathParser.java b/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/namepath/JcrPathParser.java index 120527554b..599e07f4b7 100644 --- a/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/namepath/JcrPathParser.java +++ b/oak-core-spi/src/main/java/org/apache/jackrabbit/oak/namepath/JcrPathParser.java @@ -31,7 +31,6 @@ public final class JcrPathParser { private static final int STATE_DOT = 6; private static final int STATE_DOTDOT = 7; private static final int STATE_URI = 8; - private static final int STATE_URI_END = 9; private static final char EOF = (char) -1; @@ -128,8 +127,7 @@ public final class JcrPathParser { } if (state == STATE_PREFIX || state == STATE_NAME - || state == STATE_INDEX_END - || state == STATE_URI_END) { + || state == STATE_INDEX_END) { // eof path element if (name == null) { @@ -159,14 +157,17 @@ public final class JcrPathParser { } lastPos = pos; state = STATE_PREFIX_START; - } else if (state != STATE_URI - && !(state == STATE_PREFIX_START && c == EOF)) { // ignore trailing slash - pathAwareListener.error("'" + c + "' not allowed in name."); + } else if (state == STATE_NAME_START) { + pathAwareListener.error("Local name must not be empty."); return false; } else if (state == STATE_URI && c == EOF) { // we reached EOF without finding the closing curly brace '}' pathAwareListener.error("Missing '}'."); return false; + } else if (state != STATE_URI + && !(state == STATE_PREFIX_START && c == EOF)) { // ignore trailing slash + pathAwareListener.error("'" + c + "' not allowed in name."); + return false; } break; @@ -230,7 +231,7 @@ public final class JcrPathParser { // instead of the usual namespace prefix, if it is // located at the beginning of a new segment and a '}' will follow. state = jcrPath.indexOf('}', pos) == -1 ? STATE_NAME : STATE_URI; - } else if (state == STATE_NAME_START || state == STATE_DOT || state == STATE_DOTDOT) { + } else if (state == STATE_PREFIX || state == STATE_NAME_START || state == STATE_DOT || state == STATE_DOTDOT) { // otherwise it's part of the local name state = STATE_NAME; } @@ -238,13 +239,14 @@ public final class JcrPathParser { case '}': if (state == STATE_URI) { - state = STATE_URI_END; + state = jcrPath.indexOf(':', jcrPath.lastIndexOf('{', pos)) == -1 ? + STATE_NAME : STATE_NAME_START; } else if (state == STATE_PREFIX_START || state == STATE_DOT || state == STATE_DOTDOT) { state = STATE_PREFIX; - } else if (state == STATE_NAME_START) { + } else if (state == STATE_NAME_START || state == STATE_PREFIX) { state = STATE_NAME; } else if (state == STATE_INDEX_END) { - pathAwareListener.error("'" + c + "' not valid after index. '/' expected."); + pathAwareListener.error("'" + c + "' not valid after index. '/' expected. return false; } break; diff --git a/oak-core-spi/src/test/java/org/apache/jackrabbit/oak/namepath/PathParserTest.java b/oak-core-spi/src/test/java/org/apache/jackrabbit/oak/namepath/PathParserTest.java index 81dc854a57..6880f2cc42 100755 --- a/oak-core-spi/src/test/java/org/apache/jackrabbit/oak/namepath/PathParserTest.java +++ b/oak-core-spi/src/test/java/org/apache/jackrabbit/oak/namepath/PathParserTest.java @@ -199,10 +199,7 @@ public class PathParserTest { } @Test - @Ignore //OAK-10621 - public void testExpandendName() { - boolean result; - + public void testExpandedName() { final String prefix = "{http://www.jcp.org/jcr/1.0}"; String path = prefix; TestListener listener = new TestListener( @@ -235,18 +232,53 @@ public class PathParserTest { ); verifyResult(path, listener, true); - path = "/{a}b"; + path = "/{a}b[1]"; listener = new TestListener( CALLBACKRESULT_ROOT, - CALLBACKRESULT_NAME("{a}b") + CALLBACKRESULT_NAME("{a}b", 1) ); verifyResult(path, listener, true); - path = "{a}b[1]"; + path = "/" + prefix + "b[1]"; listener = new TestListener( - CALLBACKRESULT_NAME("{a}b", 1) + CALLBACKRESULT_ROOT, + CALLBACKRESULT_NAME(prefix + "b", 1) + ); + verifyResult(path, listener, true); + + path = "{a}b[1]/c"; + listener = new TestListener( + CALLBACKRESULT_NAME("{a}b", 1), + CALLBACKRESULT_NAME("c") + ); + verifyResult(path, listener, true); + + path = prefix + "b[1]/c"; + listener = new TestListener( + CALLBACKRESULT_NAME( prefix+ "b", 1), + CALLBACKRESULT_NAME("c") + ); + verifyResult(path, listener, true); + + path = "{internal}a"; + listener = new TestListener( + CALLBACKRESULT_NAME("{internal}a") + ); + verifyResult(path, listener, true); + + path = "{a}"; + listener = new TestListener( + CALLBACKRESULT_NAME("{a}") ); verifyResult(path, listener, true); + + //"internal" is accepted as a namespace URI for backward compatabilty reasons, so + //"{internal}" is not a valid local name. + path = "{internal}"; + listener = new TestListener( + CALLBACKRESULT_ERROR(errorEmptyLocalName(path)) + ); + verifyResult(path, listener, false); } @Test @@ -482,21 +514,21 @@ public class PathParserTest { path = "/a{b}:c"; listener = new TestListener( CALLBACKRESULT_ROOT, - CALLBACKRESULT_ERROR("'/a{b}:c' is not a valid path. Invalid name prefix: a{b}") + CALLBACKRESULT_ERROR("'/a{b}:c' is not a valid path. ':' not allowed in name.") ); verifyResult(path, listener, false); path = "/a{b:c"; listener = new TestListener( CALLBACKRESULT_ROOT, - CALLBACKRESULT_ERROR("'/a{b:c' is not a valid path. Invalid name prefix: a{b") + CALLBACKRESULT_ERROR("'/a{b:c' is not a valid path. ':' not allowed in name.") ); verifyResult(path, listener, false); path = "/ab}:c"; listener = new TestListener( CALLBACKRESULT_ROOT, - CALLBACKRESULT_ERROR("'/ab}:c' is not a valid path. Invalid name prefix: ab}") + CALLBACKRESULT_ERROR("'/ab}:c' is not a valid path. ':' not allowed in name.") ); verifyResult(path, listener, false); @@ -607,9 +639,7 @@ public class PathParserTest { path = "/a:/b"; listener = new TestListener( CALLBACKRESULT_ROOT, - //TODO OAK-10616 - //the error message is could be improved (Empty local name is not allowed). - CALLBACKRESULT_ERROR("'/a:/b' is not a valid path. '/' not allowed in name.") + CALLBACKRESULT_ERROR("'/a:/b' is not a valid path. Local name must not be empty.") ); verifyResult(path, listener, false);