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);
 

Reply via email to