Author: jukka
Date: Fri Mar 28 16:25:32 2014
New Revision: 1582804
URL: http://svn.apache.org/r1582804
Log:
OAK-1174: Inconsistent handling of invalid names/paths
The spec allows whitespace in names, so the parser shouldn't balk at them.
Instead we guard against them in the NameValidator during writes.
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/JcrNameParser.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/JcrPathParser.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/Namespaces.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImplTest.java
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/NamePathTest.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/JcrNameParser.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/JcrNameParser.java?rev=1582804&r1=1582803&r2=1582804&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/JcrNameParser.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/JcrNameParser.java
Fri Mar 28 16:25:32 2014
@@ -92,7 +92,6 @@ public final class JcrNameParser {
String prefix;
int nameStart = 0;
int state = STATE_PREFIX_START;
- boolean trailingSpaces = false;
for (int i = 0; i < len; i++) {
char c = jcrName.charAt(i);
@@ -101,10 +100,6 @@ public final class JcrNameParser {
listener.error("Prefix must not be empty");
return false;
} else if (state == STATE_PREFIX) {
- if (trailingSpaces) {
- listener.error("Trailing spaces not allowed");
- return false;
- }
prefix = jcrName.substring(0, i);
if (!XMLChar.isValidNCName(prefix)) {
listener.error("Invalid name prefix: "+ prefix);
@@ -117,14 +112,7 @@ public final class JcrNameParser {
listener.error("'" + c + "' not allowed in name");
return false;
}
- trailingSpaces = false;
- } else if (c == ' ') {
- if (state == STATE_PREFIX_START || state == STATE_NAME_START) {
- listener.error("'" + c + "' not valid name start");
- return false;
- }
- trailingSpaces = true;
- } else if (Character.isWhitespace(c) || c == '[' || c == ']' || c
== '*' || c == '|') {
+ } else if (c == '[' || c == ']' || c == '*' || c == '|') {
listener.error("'" + c + "' not allowed in name");
return false;
} else if (c == '/') {
@@ -134,7 +122,6 @@ public final class JcrNameParser {
listener.error("'" + c + "' not allowed in name");
return false;
}
- trailingSpaces = false;
} else if (c == '{') {
if (state == STATE_PREFIX_START) {
state = STATE_URI_START;
@@ -147,7 +134,6 @@ public final class JcrNameParser {
state = STATE_NAME;
nameStart = i;
}
- trailingSpaces = false;
} else if (c == '}') {
if (state == STATE_URI_START || state == STATE_URI) {
String tmp = jcrName.substring(1, i);
@@ -178,7 +164,6 @@ public final class JcrNameParser {
state = STATE_NAME;
nameStart = i;
}
- trailingSpaces = false;
} else {
if (state == STATE_PREFIX_START) {
state = STATE_PREFIX; // prefix start
@@ -188,7 +173,6 @@ public final class JcrNameParser {
} else if (state == STATE_URI_START) {
state = STATE_URI;
}
- trailingSpaces = false;
}
}
@@ -203,10 +187,6 @@ public final class JcrNameParser {
listener.error("Local name must not be empty");
return false;
}
- if (trailingSpaces) {
- listener.error("Trailing spaces not allowed");
- return false;
- }
return listener.name(jcrName, index);
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/JcrPathParser.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/JcrPathParser.java?rev=1582804&r1=1582803&r2=1582804&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/JcrPathParser.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/JcrPathParser.java
Fri Mar 28 16:25:32 2014
@@ -80,11 +80,7 @@ public final class JcrPathParser {
while (pos <= len) {
char c = pos == len ? EOF : jcrPath.charAt(pos);
pos++;
- // special check for whitespace
- if (c != ' ' && Character.isWhitespace(c)) {
- c = '\t';
- }
-
+
switch (c) {
case '/':
case EOF:
@@ -205,24 +201,6 @@ public final class JcrPathParser {
}
break;
- case ' ':
- if (state == STATE_PREFIX_START || state ==
STATE_NAME_START) {
- listener.error('\'' + jcrPath + "' is not a valid
path. '" + c +
- "' not valid name start");
- return false;
- } else if (state == STATE_INDEX_END) {
- listener.error('\'' + jcrPath + "' is not a valid
path. '" + c +
- "' not valid after index. '/' expected.");
- return false;
- } else if (state == STATE_DOT || state == STATE_DOTDOT) {
- state = STATE_PREFIX;
- }
- break;
-
- case '\t':
- listener.error('\'' + jcrPath + "' is not a valid path. " +
- "Whitespace not a allowed in name.");
- return false;
case '*':
case '|':
listener.error('\'' + jcrPath + "' is not a valid path. '"
+ c +
@@ -257,7 +235,7 @@ public final class JcrPathParser {
return false;
}
}
- wasSlash = c == ' ';
+ wasSlash = c == '/';
}
return true;
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/Namespaces.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/Namespaces.java?rev=1582804&r1=1582803&r2=1582804&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/Namespaces.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/Namespaces.java
Fri Mar 28 16:25:32 2014
@@ -244,10 +244,14 @@ public class Namespaces implements Names
for (int i = 0; i < local.length(); i++) {
char ch = local.charAt(i);
- if (i == 0 && Character.isWhitespace(ch)) {
- return false; // leading whitespace
- } else if (i == local.length() - 1 && Character.isWhitespace(ch)) {
- return false; // trailing whitespace
+ if (Character.isSpaceChar(ch)) {
+ if (i == 0) {
+ return false; // leading whitespace
+ } else if (i == local.length() - 1) {
+ return false; // trailing whitespace
+ } else if (ch != ' ') {
+ return false; // only spaces are allowed as whitespace
+ }
} else if ("/:[]|*".indexOf(ch) != -1) { // TODO: XMLChar check
return false; // invalid name character
}
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImplTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImplTest.java?rev=1582804&r1=1582803&r2=1582804&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImplTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImplTest.java
Fri Mar 28 16:25:32 2014
@@ -36,14 +36,13 @@ public class NamePathMapperImplTest {
private static final Map<String, String> GLOBAL = ImmutableMap.of(
"oak-jcr", "http://www.jcp.org/jcr/1.0",
"oak-nt", "http://www.jcp.org/jcr/nt/1.0",
- "oak-mix", "http://www.jcp.org/jcr/mix/1.0",
"oak-foo", "http://www.example.com/foo",
- "oak-quu", "http://www.example.com/quu");
+ "oak-quu", "http://www.example.com/quu",
+ "oak", "http://jackrabbit.apache.org/oak/ns/1.0");
private static final Map<String, String> LOCAL = ImmutableMap.of(
"jcr-jcr", "http://www.jcp.org/jcr/1.0",
"jcr-nt", "http://www.jcp.org/jcr/nt/1.0",
- "jcr-mix", "http://www.jcp.org/jcr/mix/1.0",
"foo", "http://www.example.com/foo",
"quu", "http://www.example.com/quu");
@@ -220,4 +219,17 @@ public class NamePathMapperImplTest {
}
}
+ @Test
+ public void testWhitespace() {
+ String[] paths = new String[] {
+ " leading", "trailing\n", " ", "\t",
+ "oak: leading", "oak:trailing\n", "oak: ", "oak:\t" };
+ NamePathMapper noLocal = new NamePathMapperImpl(new LocalNameMapper(
+ GLOBAL, Collections.<String, String>emptyMap()));
+ for (String path : paths) {
+ assertEquals("without local mappings", path,
noLocal.getOakPath(path));
+ assertEquals("with local mappings", path,
npMapper.getOakPath(path));
+ }
+ }
+
}
Modified:
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/NamePathTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/NamePathTest.java?rev=1582804&r1=1582803&r2=1582804&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/NamePathTest.java
(original)
+++
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/NamePathTest.java
Fri Mar 28 16:25:32 2014
@@ -26,19 +26,27 @@ import javax.jcr.RepositoryException;
import javax.jcr.Session;
import com.google.common.collect.ImmutableList;
+
+import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-public class NamePathTest extends AbstractRepositoryTest {
+public class NamePathTest {
+
+ private Session session;
- /**
- * logger instance
- */
- private static final Logger log =
LoggerFactory.getLogger(NamePathTest.class);
+ @Before
+ public void setup() throws RepositoryException {
+ session = new Jcr()
+ .with(new OpenSecurityProvider())
+ .createRepository()
+ .login();
+ }
- public NamePathTest(NodeStoreFixture fixture) {
- super(fixture);
+ @After
+ public void teardown() throws RepositoryException {
+ session.logout();
}
@Test
@@ -47,7 +55,7 @@ public class NamePathTest extends Abstra
"//jcr:content",
"//content"
);
- testPaths(paths, getAdminSession());
+ testPaths(paths);
}
@Test
@@ -59,7 +67,7 @@ public class NamePathTest extends Abstra
"jc/r:content",
"con/ent"
);
- testNames(names, getAdminSession());
+ testNames(names);
}
@Test
@@ -67,7 +75,7 @@ public class NamePathTest extends Abstra
List<String> paths = ImmutableList.of(
"/jcr:con:ent"
);
- testPaths(paths, getAdminSession());
+ testPaths(paths);
}
@Test
@@ -75,7 +83,7 @@ public class NamePathTest extends Abstra
List<String> names = ImmutableList.of(
"jcr:con:ent"
);
- testNames(names, getAdminSession());
+ testNames(names);
}
@Test
@@ -85,7 +93,7 @@ public class NamePathTest extends Abstra
"/jcr:con]ent",
"/con]ent"
);
- testPaths(paths, getAdminSession());
+ testPaths(paths);
}
@Test
@@ -111,7 +119,7 @@ public class NamePathTest extends Abstra
"jc[r:content",
"con[ent"
);
- testNames(names, getAdminSession());
+ testNames(names);
}
@Test
@@ -124,7 +132,7 @@ public class NamePathTest extends Abstra
"/*ontent",
"/conten*"
);
- testPaths(paths, getAdminSession());
+ testPaths(paths);
}
@Test
@@ -134,10 +142,10 @@ public class NamePathTest extends Abstra
"jcr:*ontent",
"jcr:conten*",
"con*ent",
- "*ontent", // TODO fails
+ "*ontent",
"conten*"
);
- testNames(names, getAdminSession());
+ testNames(names);
}
@Test
@@ -150,7 +158,7 @@ public class NamePathTest extends Abstra
"/conten|",
"/con|ent"
);
- testPaths(paths, getAdminSession());
+ testPaths(paths);
}
@Test
@@ -160,10 +168,10 @@ public class NamePathTest extends Abstra
"jcr:|ontent",
"jcr:conten|",
"con|ent",
- "|ontent", //TODO fails
+ "|ontent",
"conten|"
);
- testNames(names, getAdminSession());
+ testNames(names);
}
@Test
@@ -177,13 +185,13 @@ public class NamePathTest extends Abstra
"con\tent"
);
- testPaths(paths, getAdminSession());
+ testPaths(paths);
}
@Test
public void testWhitespaceInName() throws Exception {
List<String> names = ImmutableList.of(
-// "jcr:content ", // FIXME OAK-1174
+ "jcr:content ",
"content ",
" content",
"jcr:content\t",
@@ -191,24 +199,23 @@ public class NamePathTest extends Abstra
"\tcontent",
"con\tent"
);
- testNames(names, getAdminSession());
+ testNames(names);
}
@Test
public void testSpaceInNames() throws RepositoryException {
- Session session = getAdminSession();
Node n = session.getRootNode().addNode("c o n t e n t");
- Node n2 = session.getNode(n.getPath());
+ session.getNode(n.getPath());
}
- private static void testPaths(List<String> paths, Session session) throws
RepositoryException {
+ private void testPaths(List<String> paths) throws RepositoryException {
for (String path : paths) {
- testPath(path, session);
+ testPath(path);
}
}
- private static void testPath(String path, Session session) throws
RepositoryException {
+ private void testPath(String path) throws RepositoryException {
RepositoryException exception = null;
try {
session.itemExists(path);
@@ -225,13 +232,13 @@ public class NamePathTest extends Abstra
}
}
- private static void testNames(List<String> names, Session session) throws
RepositoryException {
+ private void testNames(List<String> names) throws RepositoryException {
for (String name : names) {
- testName(name, session);
+ testName(name);
}
}
- private static void testName(String name, Session session) throws
RepositoryException {
+ private void testName(String name) throws RepositoryException {
Exception exception = null;
try {
session.getRootNode().addNode(name);