From 65111c6f7556527decee160246183cf1b865587e Mon Sep 17 00:00:00 2001
From: Valery Kharseko <vharseko@3a-systems.ru>
Date: Wed, 29 Jul 2026 15:05:30 +0000
Subject: [PATCH] Fix type-mismatch, index-out-of-bounds and boxed-equality CodeQL alerts (#782)

---
 opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateMessageFileMojo.java |   29 +++++++++++++++++++++--------
 opendj-server-legacy/src/main/java/org/opends/server/extensions/BCrypt.java                       |    2 +-
 opendj-server-legacy/src/messages/org/opends/messages/protocol.properties                         |    2 +-
 opendj-server-legacy/src/main/java/org/opends/server/core/EntryCacheConfigManager.java            |   10 +++++-----
 opendj-server-legacy/src/test/java/org/opends/server/extensions/BCryptTest.java                   |   13 +++++++++++++
 5 files changed, 41 insertions(+), 15 deletions(-)

diff --git a/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateMessageFileMojo.java b/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateMessageFileMojo.java
index 0e7abe7..46bb95a 100644
--- a/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateMessageFileMojo.java
+++ b/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateMessageFileMojo.java
@@ -33,6 +33,7 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Properties;
 import java.util.Set;
 import java.util.TreeMap;
@@ -145,16 +146,26 @@
         }
 
         /**
-         * Compare message entries by unique identifier.
+         * Compare message entries by ordinal, then by unique identifier.
+         * <p>
+         * Entries are held in a {@code TreeSet}, so this must be a total order:
+         * returning 0 for entries that are not the same message drops them from
+         * the log reference. Entries without an ordinal sort first, as they do
+         * in {@link MessagePropertyKey#compareTo(MessagePropertyKey)}.
          *
          * @return See {@link java.lang.Comparable#compareTo(Object)}.
          */
         @Override
         public int compareTo(MessageRefEntry mre) {
-            if (this.ordinal != null && mre.ordinal != null) {
-                return this.ordinal.compareTo(mre.ordinal);
+            if (Objects.equals(ordinal, mre.ordinal)) {
+                return xmlId.compareTo(mre.xmlId);
+            } else if (ordinal == null) {
+                return -1;
+            } else if (mre.ordinal == null) {
+                return 1;
+            } else {
+                return ordinal.compareTo(mre.ordinal);
             }
-            return 0;
         }
     }
 
@@ -245,12 +256,14 @@
 
         @Override
         public int compareTo(MessagePropertyKey k) {
-            if (ordinal == k.ordinal) {
+            if (Objects.equals(ordinal, k.ordinal)) {
                 return description.compareTo(k.description);
-            } else if (ordinal != null && k.ordinal != null) {
-                return ordinal.compareTo(k.ordinal);
+            } else if (ordinal == null) {
+                return -1;
+            } else if (k.ordinal == null) {
+                return 1;
             } else {
-                return 0;
+                return ordinal.compareTo(k.ordinal);
             }
         }
     }
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/EntryCacheConfigManager.java b/opendj-server-legacy/src/main/java/org/opends/server/core/EntryCacheConfigManager.java
index 5b59ecb..713c92a 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/EntryCacheConfigManager.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/EntryCacheConfigManager.java
@@ -13,6 +13,7 @@
  *
  * Copyright 2006-2008 Sun Microsystems, Inc.
  * Portions Copyright 2013-2016 ForgeRock AS.
+ * Portions Copyright 2026 3A Systems, LLC.
  */
 package org.opends.server.core;
 
@@ -20,7 +21,6 @@
 
 import org.forgerock.i18n.LocalizableMessage;
 import org.forgerock.i18n.slf4j.LocalizedLogger;
-import org.forgerock.opendj.ldap.ByteString;
 import org.forgerock.util.Utils;
 import org.forgerock.opendj.config.ClassPropertyDefinition;
 import org.forgerock.opendj.config.server.ConfigurationAddListener;
@@ -207,9 +207,9 @@
 
     if (!cacheOrderMap.isEmpty() && !cacheNameToLevelMap.isEmpty())
     {
-      final ByteString normDN = configuration.dn().toNormalizedByteString();
-      if (cacheNameToLevelMap.containsKey(normDN)) {
-        int currentCacheLevel = cacheNameToLevelMap.get(normDN);
+      final DN dn = configuration.dn();
+      if (cacheNameToLevelMap.containsKey(dn)) {
+        int currentCacheLevel = cacheNameToLevelMap.get(dn);
 
         // Check if there any existing cache at the same level.
         if (currentCacheLevel != configuration.getCacheLevel() &&
@@ -411,7 +411,7 @@
       }
       entryCache.finalizeEntryCache();
       cacheOrderMap.remove(configuration.getCacheLevel());
-      cacheNameToLevelMap.remove(configuration.dn().toNormalizedByteString());
+      cacheNameToLevelMap.remove(configuration.dn());
 
       // Push any changes made to the cache order map.
       setCacheOrder(cacheOrderMap);
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/extensions/BCrypt.java b/opendj-server-legacy/src/main/java/org/opends/server/extensions/BCrypt.java
index 110e7b9..3cf850e 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/extensions/BCrypt.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/extensions/BCrypt.java
@@ -437,7 +437,7 @@
    * @return  the decoded value of x
    */
   private static byte char64(char x) {
-    if (x < 0 || x > index_64.length) {
+    if (x >= index_64.length) {
       return -1;
     }
     return index_64[x];
diff --git a/opendj-server-legacy/src/messages/org/opends/messages/protocol.properties b/opendj-server-legacy/src/messages/org/opends/messages/protocol.properties
index 822087d..745726d 100644
--- a/opendj-server-legacy/src/messages/org/opends/messages/protocol.properties
+++ b/opendj-server-legacy/src/messages/org/opends/messages/protocol.properties
@@ -860,5 +860,5 @@
 ERR_SNMP_CONNHANDLER_OPENDMK_JARFILES_NOT_OPERATIONAL_1507=The required \
  classes could not be loaded using jar file '%s'. Verify that the jar file \
  is not corrupted
-ERR_HTTP_ERROR_WHILE_PROCESSING_REQUEST_1508=An error occurred while processing the request \
+ERR_HTTP_ERROR_WHILE_PROCESSING_REQUEST_1539=An error occurred while processing the request \
  %s: %s
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/extensions/BCryptTest.java b/opendj-server-legacy/src/test/java/org/opends/server/extensions/BCryptTest.java
index 926c134..865a394 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/extensions/BCryptTest.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/extensions/BCryptTest.java
@@ -24,6 +24,7 @@
  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * Portions Copyright 2026 3A Systems, LLC.
  *
  */
 
@@ -198,6 +199,18 @@
     }
 
     /**
+     * A stored password whose salt holds a character beyond the base64 decoding table
+     * must fail with the IllegalArgumentException that
+     * BcryptPasswordStorageScheme.passwordMatches() catches, and not with an
+     * ArrayIndexOutOfBoundsException escaping into bind processing.
+     */
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void checkPwRejectsSaltCharBeyondDecodingTable() {
+        // U+0080 is the first character past the end of the 128 entry index_64 table.
+        BCrypt.checkpw("secret", "$2a$10$" + ((char) 0x80) + "aaaaaaaaaaaaaaaaaaaaa");
+    }
+
+    /**
      *     Test for correct hashing of non-US-ASCII passwords.
      */
     @Test

--
Gitblit v1.10.0