From 74fe31b8864568224d9461e712d8e34e8eb8ba97 Mon Sep 17 00:00:00 2001
From: Valery Kharseko <vharseko@3a-systems.ru>
Date: Wed, 05 Aug 2026 08:33:01 +0000
Subject: [PATCH] Fix CodeQL note-severity alerts: shadowed locals, and the array cases of the debug formatter (#848)

---
 opendj-server-legacy/src/main/java/org/opends/server/loggers/DebugMessageFormatter.java        |  128 +-----------------------
 opendj-server-legacy/src/test/java/org/opends/server/loggers/DebugMessageFormatterTest.java    |   84 ++++++++++++++++
 opendj-config/src/main/java/org/forgerock/opendj/config/AggregationPropertyDefinition.java     |    7 
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java |    2 
 opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/PatternIP.java   |    9 +
 opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/PerformanceRunner.java       |   10 +-
 opendj-server-legacy/src/main/java/org/opends/server/replication/protocol/TopologyMsg.java     |   12 +-
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewGroupPanel.java      |    7 
 8 files changed, 118 insertions(+), 141 deletions(-)

diff --git a/opendj-config/src/main/java/org/forgerock/opendj/config/AggregationPropertyDefinition.java b/opendj-config/src/main/java/org/forgerock/opendj/config/AggregationPropertyDefinition.java
index 2c41d7e..4b4a858 100644
--- a/opendj-config/src/main/java/org/forgerock/opendj/config/AggregationPropertyDefinition.java
+++ b/opendj-config/src/main/java/org/forgerock/opendj/config/AggregationPropertyDefinition.java
@@ -13,6 +13,7 @@
  *
  * Copyright 2007-2008 Sun Microsystems, Inc.
  * Portions Copyright 2014-2016 ForgeRock AS.
+ * Portions Copyright 2026 3A Systems, LLC.
  */
 package org.forgerock.opendj.config;
 
@@ -256,13 +257,13 @@
             } catch (ConfigException e) {
                 // The condition could not be evaluated.
                 debugLogger.trace("Unable to perform post add", e);
-                LocalizableMessage message =
+                LocalizableMessage errorMessage =
                     ERR_REFINT_UNABLE_TO_EVALUATE_TARGET_CONDITION.get(mo.getManagedObjectDefinition()
                         .getUserFriendlyName(), mo.getDN(), getExceptionMessage(e));
                 LocalizedLogger logger =
                     LocalizedLogger.getLocalizedLogger(ERR_REFINT_UNABLE_TO_EVALUATE_TARGET_CONDITION.resourceName());
-                logger.error(message);
-                unacceptableReasons.add(message);
+                logger.error(errorMessage);
+                unacceptableReasons.add(errorMessage);
                 return false;
             }
         }
diff --git a/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/PerformanceRunner.java b/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/PerformanceRunner.java
index fde226f..a64cd2b 100644
--- a/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/PerformanceRunner.java
+++ b/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/PerformanceRunner.java
@@ -129,14 +129,14 @@
         @Override
         public void run() {
             Promise<?, LdapException> promise;
-            Connection connection;
+            Connection connectionToUse;
             final double targetTimeMs = 1000.0 / (targetThroughput / (double) (numThreads * numConnections));
             double sleepTimeMs = 0;
 
             while (!stopRequested && !localStopRequested
                     && (maxIterations <= 0 || count < maxIterations)) {
                 try {
-                    connection = getConnectionToUse();
+                    connectionToUse = getConnectionToUse();
                 } catch (final InterruptedException e) {
                     // Ignore and check stop requested
                     continue;
@@ -146,7 +146,7 @@
                 }
 
                 long startTimeNs = System.nanoTime();
-                promise = performOperation(connection, dataSources.get(), startTimeNs);
+                promise = performOperation(connectionToUse, dataSources.get(), startTimeNs);
                 statsThread.incrementOperationCount();
                 try {
                     promise.getOrThrow();
@@ -161,8 +161,8 @@
                     }
                     // Ignore. Handled by result handler
                 } finally {
-                    if (this.connection == null) {
-                        connection.close();
+                    if (connection == null) {
+                        connectionToUse.close();
                     }
                 }
 
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java
index 99f8edc..8aa560a 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java
@@ -618,7 +618,7 @@
                 }
               });
             }
-            catch (Throwable t)
+            catch (Throwable th)
             {
               entryReader = null;
             }
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewGroupPanel.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewGroupPanel.java
index 0f4fd49..054874a 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewGroupPanel.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewGroupPanel.java
@@ -13,6 +13,7 @@
  *
  * Copyright 2008-2010 Sun Microsystems, Inc.
  * Portions Copyright 2013-2016 ForgeRock AS.
+ * Portions Copyright 2026 3A Systems, LLC.
  */
 package org.opends.guitools.controlpanel.ui;
 
@@ -343,17 +344,17 @@
     dynamicGroup.addActionListener(actionListener);
     virtualGroup.addActionListener(actionListener);
 
-    JLabel[] labels = {lName, lDescription, lMembers};
+    JLabel[] layoutLabels = {lName, lDescription, lMembers};
     Component[] comps = {name, description, staticGroup};
     Component[] inlineHelp = {null, null, null};
 
-    for (i=0 ; i< labels.length; i++)
+    for (i=0 ; i< layoutLabels.length; i++)
     {
       gbc.insets.left = 0;
       gbc.weightx = 0.0;
       gbc.gridx = 0;
       gbc.gridwidth = 1;
-      add(labels[i], gbc);
+      add(layoutLabels[i], gbc);
       gbc.insets.left = 10;
       gbc.weightx = 1.0;
       gbc.gridx = 1;
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/PatternIP.java b/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/PatternIP.java
index 7f90edb..2190ffb 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/PatternIP.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/PatternIP.java
@@ -13,6 +13,7 @@
  *
  * Copyright 2008 Sun Microsystems, Inc.
  * Portions Copyright 2014-2016 ForgeRock AS.
+ * Portions Copyright 2026 3A Systems, LLC.
  */
 package org.opends.server.authorization.dseecompat;
 
@@ -386,17 +387,17 @@
      */
     public EnumEvalResult evaluate(InetAddress remoteAddr) {
         EnumEvalResult matched=EnumEvalResult.FALSE;
-        IPType ipType=IPType.IPv4;
+        IPType remoteIpType=IPType.IPv4;
         byte[] addressBytes=remoteAddr.getAddress();
         if(remoteAddr instanceof Inet6Address) {
-            ipType=IPType.IPv6;
+            remoteIpType=IPType.IPv6;
             Inet6Address addr6 = (Inet6Address) remoteAddr;
             addressBytes= addr6.getAddress();
             if(addr6.isIPv4CompatibleAddress()) {
-                ipType=IPType.IPv4;
+                remoteIpType=IPType.IPv4;
             }
         }
-        if(ipType != this.ipType) {
+        if(remoteIpType != ipType) {
             return EnumEvalResult.FALSE;
         }
         if(matchAddress(addressBytes)) {
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/loggers/DebugMessageFormatter.java b/opendj-server-legacy/src/main/java/org/opends/server/loggers/DebugMessageFormatter.java
index cb17460..04b8f4c 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/loggers/DebugMessageFormatter.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/loggers/DebugMessageFormatter.java
@@ -13,9 +13,11 @@
  *
  * Copyright 2006-2008 Sun Microsystems, Inc.
  * Portions Copyright 2014-2015 ForgeRock AS.
+ * Portions Copyright 2026 3A Systems, LLC.
  */
 package org.opends.server.loggers;
 
+import java.lang.reflect.Array;
 import java.util.Arrays;
 import java.util.IllegalFormatException;
 import java.util.Iterator;
@@ -96,26 +98,9 @@
     else if (arg instanceof Object[]) {
       decoratedArg= decorateArrayArg((Object[])arg);
     }
-    else if (arg instanceof boolean[]) {
-      decoratedArg = decorateArrayArg((boolean[])arg);
-    }
-    else if (arg instanceof byte[]) {
-      decoratedArg = decorateArrayArg((byte[])arg);
-    }
-    else if (arg instanceof char[]) {
-      decoratedArg = decorateArrayArg((char[])arg);
-    }
-    else if (arg instanceof double[]) {
-      decoratedArg = decorateArrayArg((double[])arg);
-    }
-    else if (arg instanceof float[]) {
-      decoratedArg = decorateArrayArg((float[])arg);
-    }
-    else if (arg instanceof int[]) {
-      decoratedArg = decorateArrayArg((int[])arg);
-    }
-    else if (arg instanceof long[]) {
-      decoratedArg = decorateArrayArg((long[])arg);
+    else if (arg != null && arg.getClass().isArray()) {
+      // Any array of a primitive type. Its elements need no decoration of their own.
+      decoratedArg = decoratePrimitiveArrayArg(arg);
     }
 
     return decoratedArg;
@@ -126,112 +111,17 @@
     return decorateListArg(Arrays.asList(array));
   }
 
-  private static String decorateArrayArg(boolean[] array)
+  private static String decoratePrimitiveArrayArg(Object array)
   {
     StringBuilder buffer= new StringBuilder();
     buffer.append("[ ");
-    for (int i= 0; i < array.length; i++) {
+    int length= Array.getLength(array);
+    for (int i= 0; i < length; i++) {
       if (i > 0)
       {
         buffer.append(", ");
       }
-      buffer.append(array[i]);
-    }
-    buffer.append(" ]");
-
-    return buffer.toString();
-  }
-
-  private static String decorateArrayArg(byte[] array)
-  {
-    StringBuilder buffer= new StringBuilder();
-    buffer.append("[ ");
-    for (int i= 0; i < array.length; i++) {
-      if (i > 0)
-      {
-        buffer.append(", ");
-      }
-      buffer.append(array[i]);
-    }
-    buffer.append(" ]");
-
-    return buffer.toString();
-  }
-
-  private static String decorateArrayArg(char[] array)
-  {
-    StringBuilder buffer= new StringBuilder();
-    buffer.append("[ ");
-    for (int i= 0; i < array.length; i++) {
-      if (i > 0)
-      {
-        buffer.append(", ");
-      }
-      buffer.append(array[i]);
-    }
-    buffer.append(" ]");
-
-    return buffer.toString();
-  }
-
-  private static String decorateArrayArg(double[] array)
-  {
-    StringBuilder buffer= new StringBuilder();
-    buffer.append("[ ");
-    for (int i= 0; i < array.length; i++) {
-      if (i > 0)
-      {
-        buffer.append(", ");
-      }
-      buffer.append(array[i]);
-    }
-    buffer.append(" ]");
-
-    return buffer.toString();
-  }
-
-  private static String decorateArrayArg(float[] array)
-  {
-    StringBuilder buffer= new StringBuilder();
-    buffer.append("[ ");
-    for (int i= 0; i < array.length; i++) {
-      if (i > 0)
-      {
-        buffer.append(", ");
-      }
-      buffer.append(array[i]);
-    }
-    buffer.append(" ]");
-
-    return buffer.toString();
-  }
-
-  private static String decorateArrayArg(int[] array)
-  {
-    StringBuilder buffer= new StringBuilder();
-    buffer.append("[ ");
-    for (int i= 0; i < array.length; i++) {
-      if (i > 0)
-      {
-        buffer.append(", ");
-      }
-      buffer.append(array[i]);
-    }
-    buffer.append(" ]");
-
-    return buffer.toString();
-  }
-
-  private static String decorateArrayArg(long[] array)
-  {
-    StringBuilder buffer= new StringBuilder();
-    buffer.append("[ ");
-    for (int i= 0; i < array.length; i++) {
-      if (i > 0)
-      {
-        buffer.append(", ");
-      }
-      buffer.append(array[i]);
+      buffer.append(Array.get(array, i));
     }
     buffer.append(" ]");
 
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/replication/protocol/TopologyMsg.java b/opendj-server-legacy/src/main/java/org/opends/server/replication/protocol/TopologyMsg.java
index 8ed3986..c37a63d 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/replication/protocol/TopologyMsg.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/replication/protocol/TopologyMsg.java
@@ -70,25 +70,25 @@
 
     // Read the DS info entries, first read number of them
     int nDsInfo = scanner.nextByte();
-    final Map<Integer, DSInfo> replicaInfos = new HashMap<>(Math.max(0, nDsInfo));
+    final Map<Integer, DSInfo> newReplicaInfos = new HashMap<>(Math.max(0, nDsInfo));
     while (nDsInfo > 0 && !scanner.isEmpty())
     {
       final DSInfo dsInfo = nextDSInfo(scanner, version);
-      replicaInfos.put(dsInfo.getDsId(), dsInfo);
+      newReplicaInfos.put(dsInfo.getDsId(), dsInfo);
       nDsInfo--;
     }
 
     // Read the RS info entries
     int nRsInfo = scanner.nextByte();
-    final List<RSInfo> rsInfos = new ArrayList<>(Math.max(0, nRsInfo));
+    final List<RSInfo> newRsInfos = new ArrayList<>(Math.max(0, nRsInfo));
     while (nRsInfo > 0 && !scanner.isEmpty())
     {
-      rsInfos.add(nextRSInfo(scanner, version));
+      newRsInfos.add(nextRSInfo(scanner, version));
       nRsInfo--;
     }
 
-    this.replicaInfos = Collections.unmodifiableMap(replicaInfos);
-    this.rsInfos = Collections.unmodifiableList(rsInfos);
+    this.replicaInfos = Collections.unmodifiableMap(newReplicaInfos);
+    this.rsInfos = Collections.unmodifiableList(newRsInfos);
   }
 
   private DSInfo nextDSInfo(ByteArrayScanner scanner, short version)
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/loggers/DebugMessageFormatterTest.java b/opendj-server-legacy/src/test/java/org/opends/server/loggers/DebugMessageFormatterTest.java
new file mode 100644
index 0000000..a49c5d1
--- /dev/null
+++ b/opendj-server-legacy/src/test/java/org/opends/server/loggers/DebugMessageFormatterTest.java
@@ -0,0 +1,84 @@
+/*
+ * The contents of this file are subject to the terms of the Common Development and
+ * Distribution License (the License). You may not use this file except in compliance with the
+ * License.
+ *
+ * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
+ * specific language governing permission and limitations under the License.
+ *
+ * When distributing Covered Software, include this CDDL Header Notice in each file and include
+ * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
+ * Header, with the fields enclosed by brackets [] replaced by your own identifying
+ * information: "Portions copyright [year] [name of copyright owner]".
+ *
+ * Copyright 2026 3A Systems, LLC.
+ */
+package org.opends.server.loggers;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.opends.server.DirectoryServerTestCase;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/** Tests the decoration of the arguments of a debug log message. */
+@SuppressWarnings("javadoc")
+public class DebugMessageFormatterTest extends DirectoryServerTestCase
+{
+  @DataProvider
+  public Object[][] arrayArguments()
+  {
+    return new Object[][] {
+      { new boolean[] { true, false },    "[ true, false ]" },
+      { new byte[] { 1, -2 },             "[ 1, -2 ]" },
+      { new char[] { 'a', 'b' },          "[ a, b ]" },
+      { new double[] { 1.5, 2.0 },        "[ 1.5, 2.0 ]" },
+      { new float[] { 1.5f, 2.0f },       "[ 1.5, 2.0 ]" },
+      { new int[] { 1, 2 },               "[ 1, 2 ]" },
+      { new long[] { 1L, 2L },            "[ 1, 2 ]" },
+      { new short[] { 1, 2 },             "[ 1, 2 ]" },
+      { new String[] { "a", "b" },        "[ a, b ]" },
+      { new boolean[0],                   "[  ]" },
+    };
+  }
+
+  /** Arrays are formatted element by element, whatever their component type. */
+  @Test(dataProvider = "arrayArguments")
+  public void testArrayArgumentIsDecorated(Object array, String expected)
+  {
+    assertThat(DebugMessageFormatter.format("%s", new Object[] { array })).isEqualTo(expected);
+  }
+
+  /** Lists, maps and object arrays decorate their elements in turn. */
+  @Test
+  public void testNestedArgumentsAreDecorated()
+  {
+    final Map<String, Object> map = new LinkedHashMap<>();
+    map.put("key", new int[] { 1, 2 });
+
+    assertThat(DebugMessageFormatter.format("%s", new Object[] { map })).isEqualTo("{ key=[ 1, 2 ] }");
+    assertThat(DebugMessageFormatter.format("%s", new Object[] { Arrays.asList("a", new int[] { 3 }) }))
+        .isEqualTo("[ a, [ 3 ] ]");
+    assertThat(DebugMessageFormatter.format("%s", new Object[] { new Object[] { new char[] { 'x' } } }))
+        .isEqualTo("[ [ x ] ]");
+  }
+
+  @Test
+  public void testNonArrayArgumentsAreLeftAlone()
+  {
+    assertThat(DebugMessageFormatter.format("%s and %s", new Object[] { "text", 42 })).isEqualTo("text and 42");
+    assertThat(DebugMessageFormatter.format("%s", new Object[] { null })).isEqualTo("null");
+  }
+
+  /** A format string which does not match its arguments falls back to concatenation. */
+  @Test
+  public void testInvalidFormatFallsBackToConcatenation()
+  {
+    assertThat(DebugMessageFormatter.format("%d", new Object[] { new int[] { 1 } })).isEqualTo("%d [ 1 ]");
+    assertThat(DebugMessageFormatter.format(null, new Object[] { new int[] { 1 } })).isEqualTo(" [ 1 ]");
+  }
+}

--
Gitblit v1.10.0