mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Yannick Lecaillez
29.56.2016 e7575a3dec0c906fada777fe340c9ed767d3e173
Fix: isChild() mistakenly report parent-child relationship.

The problem happen when DN's share the same prefix. i.e:
ou=people1,uid=user1 were considered to be a child of ou=people because
"ou=people1,uid=user1".startsWith("ou=people") is true
2 files modified
52 ■■■■■ changed files
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/DnKeyFormat.java 12 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/TestDnKeyFormat.java 40 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/DnKeyFormat.java
@@ -118,23 +118,25 @@
   */
  static boolean isChild(ByteSequence parent, ByteSequence child)
  {
    if (!child.startsWith(parent))
    if (child.length() <= parent.length()
        || child.byteAt(parent.length()) != NORMALIZED_RDN_SEPARATOR
        || !child.startsWith(parent))
    {
      return false;
    }
    // Immediate children should only have one RDN separator past the parent length
    int nbSeparator = 0;
    boolean childSeparatorDetected = false;
    for (int i = parent.length() ; i < child.length(); i++)
    {
      if (child.byteAt(i) == NORMALIZED_RDN_SEPARATOR)
      {
        nbSeparator++;
        if (nbSeparator > 1)
        if (childSeparatorDetected)
        {
          return false;
        }
        childSeparatorDetected = true;
      }
    }
    return nbSeparator == 1;
    return childSeparatorDetected;
  }
}
opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/TestDnKeyFormat.java
@@ -497,6 +497,46 @@
    assertThat(DnKeyFormat.findDNKeyParent(dnKey)).isEqualTo(expectedLength);
  }
  @DataProvider
  private Object[][] testIsChildData()
  {
    return new Object[][]
    {
      {           "dc=example,dc=com\\,org", // parentDn
        "ou=people,dc=example,dc=com\\,org", // childDn
        true },                              // Is childDn a child of parentDn ?
      { "dc=example,dc=com",
                   "dc=com",
        false },
      {  "ou=people,dc=example,dc=com",
        "ou=people1,dc=example,dc=com",
        false },
      {                      "dc=example,dc=com",
        "uid=user.0,ou=people,dc=example,dc=com",
        false },
      {           "dc=example,dc=com",
        "ou=people,dc=elpmaxe,dc=com",
        false },
      { "dc=example,dc=com",
        "dc=example,dc=com",
        false },
    };
  }
  @Test(dataProvider="testIsChildData")
  public void testIsChild(String parentDn, String childDn, boolean expected) {
    assertThat(
      DnKeyFormat.isChild(
          DnKeyFormat.dnToDNKey(DN.valueOf(parentDn), 0),
          DnKeyFormat.dnToDNKey(DN.valueOf(childDn), 0))
      ).isEqualTo(expected);
  }
  private void ensureServerIsUpAndRunning() throws Exception
  {
    TestCaseUtils.startServer();