Index: oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/ValidNamesTest.java =================================================================== --- oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/ValidNamesTest.java (revision 1781053) +++ oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/ValidNamesTest.java (working copy) @@ -264,10 +264,8 @@ nameTest("foo\u3000bar"); } - @Test + @Test(expected = IllegalStateException.class) public void testUnpairedSurrogate() throws RepositoryException { - // see OAK-5506 - org.junit.Assume.assumeFalse(super.fixture.toString().toLowerCase().contains("segment")); nameTest("foo\ud800"); } Index: oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java =================================================================== --- oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java (revision 1781053) +++ oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java (working copy) @@ -433,7 +433,8 @@ new SyncExternalUsersTest(numberOfUsers.value(options), numberOfGroups.value(options), expiration.value(options), dynamicMembership.value(options), autoMembership.values(options), batchSize.value(options)), new HybridIndexTest(base.value(options), statsProvider), new BundlingNodeTest(), - new PersistentCacheTest(statsProvider) + new PersistentCacheTest(statsProvider), + new StringWriteTest() }; Set argset = Sets.newHashSet(nonOption.values(options)); Index: oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/StringWriteTest.java =================================================================== --- oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/StringWriteTest.java (nonexistent) +++ oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/StringWriteTest.java (working copy) @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jackrabbit.oak.benchmark; + +import java.util.UUID; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +public class StringWriteTest extends AbstractTest { + + private static final int PROPERTY_COUNT = Integer.getInteger("StringWriteTest.propertyCount", 100); + + private static String randomString() { + return UUID.randomUUID().toString(); + } + + private Session session; + + private Node root; + + @Override + public void beforeSuite() throws RepositoryException { + session = loginWriter(); + } + + @Override + protected void beforeTest() throws Exception { + root = session.getRootNode().addNode("StringWrite" + TEST_ID, "nt:unstructured"); + session.save(); + } + + @Override + protected void runTest() throws Exception { + for (int i = 0; i < PROPERTY_COUNT; i++) { + root.setProperty(randomString(), randomString()); + } + session.save(); + } + + @Override + protected void afterTest() throws Exception { + root.remove(); + session.save(); + } + +} Property changes on: oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/StringWriteTest.java ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentWriter.java =================================================================== --- oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentWriter.java (revision 1781053) +++ oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentWriter.java (working copy) @@ -87,6 +87,24 @@ static final int BLOCK_SIZE = 1 << 12; // 4kB + private static void checkValidString(String s) throws IOException { + for (int i = 0; i < s.length(); i++) { + char c1 = s.charAt(i); + if (Character.isSurrogate(c1)) { + try { + char c2 = s.charAt(i + 1); + if (Character.isSurrogatePair(c1, c2)) { + i += 1; + } else { + throw new IOException("Invalid surrogate pair sequence: " + (int) c1 + " " + (int) c2); + } + } catch (IndexOutOfBoundsException ex) { + throw new IOException("String ends in unpaired surrogate character.", ex); + } + } + } + } + @Nonnull private final WriterCacheManager cacheManager; @@ -687,6 +705,8 @@ return id; // shortcut if the same string was recently stored } + checkValidString(string); + byte[] data = string.getBytes(UTF_8); if (data.length < Segment.MEDIUM_LIMIT) {