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

Valery Kharseko
15 hours ago 3f4deb91789189521d577457bd6da27de8fd75b1
opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/PatternDN.java
@@ -13,9 +13,11 @@
 *
 * Copyright 2008 Sun Microsystems, Inc.
 * Portions Copyright 2014-2016 ForgeRock AS.
 * Portions Copyright 2026 3A Systems, LLC.
 */
package org.opends.server.authorization.dseecompat;
import static com.forgerock.opendj.ldap.CoreMessages.ERR_ATTR_SYNTAX_DN_TRAILING_ESCAPE;
import static org.opends.messages.AccessControlMessages.*;
import static org.opends.messages.SchemaMessages.*;
import static org.opends.server.util.CollectionUtils.*;
@@ -973,7 +975,13 @@
    // Look at the first character.  If it is an octothorpe (#), then
    // that means that the value should be a hex string.
    char c = dnString.charAt(pos++);
    if (c == '#')
    if (c == ',' || c == ';' || c == '+')
    {
      // The value is empty and followed by the next RDN or AVA, as DN.valueOf() reads it.
      attributeValues.add(ByteString.empty());
      return pos - 1;
    }
    else if (c == '#')
    {
      // The first two characters must be hex characters.
      StringBuilder hexString = new StringBuilder();
@@ -999,7 +1007,7 @@
      // The rest of the value must be a multiple of two hex
      // characters.  The end of the value may be designated by the
      // end of the DN, a comma or semicolon, or a space.
      // end of the DN, a comma or semicolon, a plus sign, or a space.
      while (pos < length)
      {
        c = dnString.charAt(pos++);
@@ -1026,7 +1034,7 @@
            throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX, message);
          }
        }
        else if (c == ' ' || c == ',' || c == ';')
        else if (c == ' ' || c == ',' || c == ';' || c == '+')
        {
          // This denotes the end of the value.
          pos--;
@@ -1063,6 +1071,7 @@
      // Keep reading until we find an unescaped closing quotation mark.
      boolean escaped = false;
      StringBuilder valueString = new StringBuilder();
      StringBuilder hexChars = new StringBuilder();
      while (true)
      {
        if (pos >= length)
@@ -1076,9 +1085,18 @@
        c = dnString.charAt(pos++);
        if (escaped)
        {
          // The previous character was an escape, so we'll take this
          // one no matter what.
          valueString.append(c);
          // The previous character was an escape. As in an unquoted value, and as DN.valueOf() reads
          // a quoted value, an escaped pair of hex digits is one byte of the UTF-8 encoded value.
          if (isHexDigit(c) && pos < length && isHexDigit(dnString.charAt(pos)))
          {
            hexChars.append(c);
            hexChars.append(dnString.charAt(pos++));
          }
          else
          {
            appendHexChars(dnString, valueString, hexChars);
            valueString.append(c);
          }
          escaped = false;
        }
        else if (c == '\\')
@@ -1090,12 +1108,14 @@
        else if (c == '"')
        {
          // This is the end of the value.
          appendHexChars(dnString, valueString, hexChars);
          break;
        }
        else
        {
          // This is just a regular character that should be in the
          // value.
          appendHexChars(dnString, valueString, hexChars);
          valueString.append(c);
        }
      }
@@ -1131,6 +1151,12 @@
      {
        if (pos >= length)
        {
          if (escaped)
          {
            // A lone backslash at the end, which DN.valueOf() rejects with the same message.
            throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
                ERR_ATTR_SYNTAX_DN_TRAILING_ESCAPE.get(dnString));
          }
          // This is the end of the DN and therefore the end of the value.
          // If there are any hex characters, then we need to deal with them accordingly.
          appendHexChars(dnString, valueString, hexChars);