From fb249f25fe98af8c2dcbf498872fd48c2c3ed854 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Wed, 10 Jun 2015 22:03:01 +0000
Subject: [PATCH] OPENDJ-2090 - fix bounds checking for DN2ID children and subtree cursors.

---
 opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/pdb/PDBTestCase.java              |    2 ++
 opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/DN2ID.java                        |   12 ++++++------
 opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/PluggableBackendImplTestCase.java |   35 ++++++++++++++++++++++++++---------
 3 files changed, 34 insertions(+), 15 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/DN2ID.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/DN2ID.java
index 6899251..777513a 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/DN2ID.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/DN2ID.java
@@ -206,14 +206,14 @@
    */
   private static final class ChildrenCursor extends SequentialCursorForwarding {
     private final ByteStringBuilder builder;
-    private final ByteString parentDN;
+    private final ByteString limit;
     private boolean cursorOnParent;
 
     ChildrenCursor(Cursor<ByteString, ByteString> delegate)
     {
       super(delegate);
       builder = new ByteStringBuilder(128);
-      parentDN = delegate.isDefined() ? delegate.getKey() : null;
+      limit = delegate.isDefined() ? afterKey(delegate.getKey()).toByteString() : null;
       cursorOnParent = true;
     }
 
@@ -228,7 +228,7 @@
         // Go to the next sibling
         delegate.positionToKeyOrNext(nextSibling());
       }
-      return isDefined() && delegate.getKey().startsWith(parentDN);
+      return isDefined() && delegate.getKey().compareTo(limit) < 0;
     }
 
     private ByteStringBuilder nextSibling()
@@ -242,18 +242,18 @@
    * at creation.
    */
   private static final class SubtreeCursor extends SequentialCursorForwarding {
-    private final ByteString baseDN;
+    private final ByteString limit;
 
     SubtreeCursor(Cursor<ByteString, ByteString> delegate)
     {
       super(delegate);
-      baseDN = delegate.isDefined() ? delegate.getKey() : null;
+      limit = delegate.isDefined() ? afterKey(delegate.getKey()).toByteString() : null;
     }
 
     @Override
     public boolean next()
     {
-      return delegate.next() && delegate.getKey().startsWith(baseDN);
+      return delegate.next() && delegate.getKey().compareTo(limit) < 0;
     }
   }
 
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/PluggableBackendImplTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/PluggableBackendImplTestCase.java
index 8ed3311..1be05b4 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/PluggableBackendImplTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/PluggableBackendImplTestCase.java
@@ -83,6 +83,7 @@
 import org.testng.Reporter;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
 /**
@@ -527,7 +528,7 @@
 
     dnToMod = workEntries.get(0).getName();
     dnToDel = workEntries.get(1).getName();
-    searchDN = entries.get(8).getName();
+    searchDN = entries.get(1).getName();
     badEntryDN = testBaseDN.child(DN.valueOf("ou=bogus")).child(DN.valueOf("ou=dummy"));
     backupID = "backupID1";
 
@@ -759,20 +760,36 @@
         "Subtree search should return a correct number of entries");
   }
 
-  @Test(dependsOnMethods = { "testAdd", "testModifyEntry", "testRenameEntry", "testDeleteAlreadyDeletedEntry" })
-  public void testUserEntrySearch() throws Exception
+
+  @DataProvider(name = "userEntrySearchData")
+  protected Object[][] userEntrySearchData()
   {
-    userEntrySearch(false);
-    userEntrySearch(true);
+    return new Object[][] {
+      // @formatter:off
+      { true,  SearchScope.BASE_OBJECT, 1 },
+      { false, SearchScope.BASE_OBJECT, 1 },
+      { true,  SearchScope.SINGLE_LEVEL, 0 },
+      { false, SearchScope.SINGLE_LEVEL, 0 },
+      { true,  SearchScope.WHOLE_SUBTREE, 1 },
+      { false, SearchScope.WHOLE_SUBTREE, 1 },
+      // @formatter:on
+    };
   }
 
-  private void userEntrySearch(boolean useInternalConnection) throws Exception
+  @Test(dataProvider = "userEntrySearchData",
+      dependsOnMethods = { "testAdd", "testModifyEntry", "testRenameEntry", "testDeleteAlreadyDeletedEntry" })
+  public void testUserEntrySearch(boolean useInternalConnection, SearchScope scope, int expectedEntryCount)
+      throws Exception
   {
-    SearchRequest request = newSearchRequest(searchDN, SearchScope.BASE_OBJECT, "objectclass=*");
+    SearchRequest request = newSearchRequest(searchDN, scope, "objectclass=*");
     List<SearchResultEntry> result = runSearch(request, useInternalConnection);
 
-    assertEquals(result.size(), 1, "User entry search should return a single child entry");
-    assertEquals(searchDN, result.get(0).getName(), "User entry search should return the expected entry");
+    assertEquals(result.size(), expectedEntryCount, "User entry search should return " + expectedEntryCount
+        + " child entry");
+    if (expectedEntryCount > 0)
+    {
+      assertEquals(searchDN, result.get(0).getName(), "User entry search should return the expected entry");
+    }
   }
 
   @Test(dependsOnMethods = { "testAdd", "testModifyEntry", "testRenameEntry", "testDeleteAlreadyDeletedEntry" })
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/pdb/PDBTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/pdb/PDBTestCase.java
index 34c3c1c..dedd679 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/pdb/PDBTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/pdb/PDBTestCase.java
@@ -32,10 +32,12 @@
 import org.opends.server.admin.std.server.PDBBackendCfg;
 import org.opends.server.backends.pdb.PDBBackend;
 import org.opends.server.backends.pluggable.PluggableBackendImplTestCase;
+import org.testng.annotations.Test;
 
 /**
  * PDBBackend Tester.
  */
+@Test
 public class PDBTestCase extends PluggableBackendImplTestCase<PDBBackendCfg>
 {
   @Override

--
Gitblit v1.10.0