This is an automated email from the ASF dual-hosted git repository.

hansva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git


The following commit(s) were added to refs/heads/main by this push:
     new b1dd370540 Fix Sonar warning avoid regex with potential backtracking 
(ReDoS risk) (#6996)
b1dd370540 is described below

commit b1dd370540a4f291a9af6dbf78756fb0aae111a3
Author: Lance <[email protected]>
AuthorDate: Tue Apr 14 17:59:05 2026 +0800

    Fix Sonar warning avoid regex with potential backtracking (ReDoS risk) 
(#6996)
    
    Signed-off-by: lance <[email protected]>
---
 .../java/org/apache/hop/core/util/StringUtil.java     |  5 ++---
 .../java/org/apache/hop/core/util/StringUtilTest.java |  2 ++
 .../hop/projects/git/BitbucketRepositoryBrowser.java  | 19 ++++++-------------
 .../hop/projects/git/GitHubRepositoryBrowser.java     |  3 ++-
 .../hop/projects/git/GitLabRepositoryBrowser.java     | 11 +++++------
 .../hop/projects/gui/SelectRepositoryDialog.java      | 19 ++++++-------------
 6 files changed, 23 insertions(+), 36 deletions(-)

diff --git a/core/src/main/java/org/apache/hop/core/util/StringUtil.java 
b/core/src/main/java/org/apache/hop/core/util/StringUtil.java
index 9f8880d006..8219bf5b83 100644
--- a/core/src/main/java/org/apache/hop/core/util/StringUtil.java
+++ b/core/src/main/java/org/apache/hop/core/util/StringUtil.java
@@ -602,12 +602,11 @@ public class StringUtil {
    * @return a new string with all instances of the specified character 
removed from the end
    */
   public static String trimEnd(final String source, char c) {
-    if (source == null) {
-      return null;
+    if (source == null || source.isEmpty()) {
+      return source;
     }
 
     int index = source.length();
-
     while (index > 0 && source.charAt(index - 1) == c) {
       index--;
     }
diff --git a/core/src/test/java/org/apache/hop/core/util/StringUtilTest.java 
b/core/src/test/java/org/apache/hop/core/util/StringUtilTest.java
index 2a1687e315..fa4222d476 100644
--- a/core/src/test/java/org/apache/hop/core/util/StringUtilTest.java
+++ b/core/src/test/java/org/apache/hop/core/util/StringUtilTest.java
@@ -217,5 +217,7 @@ class StringUtilTest {
   @Test
   void testTrimEnd_None() {
     assertEquals("/file/path", StringUtil.trimEnd("/file/path", '/'));
+    assertEquals("", StringUtil.trimEnd("/", '/'));
+    assertEquals("", StringUtil.trimEnd("///", '/'));
   }
 }
diff --git 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/git/BitbucketRepositoryBrowser.java
 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/git/BitbucketRepositoryBrowser.java
index 1aea2553f3..1ad7b2d1e3 100644
--- 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/git/BitbucketRepositoryBrowser.java
+++ 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/git/BitbucketRepositoryBrowser.java
@@ -28,6 +28,7 @@ import java.util.ArrayList;
 import java.util.Base64;
 import java.util.List;
 import org.apache.hop.core.exception.HopException;
+import org.apache.hop.core.util.StringUtil;
 import org.json.simple.JSONArray;
 import org.json.simple.JSONObject;
 import org.json.simple.parser.JSONParser;
@@ -55,7 +56,7 @@ class BitbucketRepositoryBrowser implements 
GitRepositoryBrowser {
 
     String base =
         (apiBaseUrl != null && !apiBaseUrl.isBlank())
-            ? apiBaseUrl.replaceAll("/+$", "")
+            ? StringUtil.trimEnd(apiBaseUrl, '/')
             : DEFAULT_API;
 
     // /repositories/{workspace} lists repos for one workspace; /repositories 
lists all the user
@@ -71,13 +72,9 @@ class BitbucketRepositoryBrowser implements 
GitRepositoryBrowser {
             .append("&sort=-updated_on");
 
     if (searchQuery != null && !searchQuery.isBlank()) {
-      try {
-        url.append("&q=name+%7E+%22")
-            .append(java.net.URLEncoder.encode(searchQuery, "UTF-8"))
-            .append("%22");
-      } catch (java.io.UnsupportedEncodingException e) {
-        // UTF-8 is always supported
-      }
+      url.append("&q=name+%7E+%22")
+          .append(java.net.URLEncoder.encode(searchQuery, 
StandardCharsets.UTF_8))
+          .append("%22");
     }
 
     String credentials =
@@ -180,10 +177,6 @@ class BitbucketRepositoryBrowser implements 
GitRepositoryBrowser {
   }
 
   private static String encode(String value) {
-    try {
-      return java.net.URLEncoder.encode(value, "UTF-8");
-    } catch (java.io.UnsupportedEncodingException e) {
-      return value;
-    }
+    return java.net.URLEncoder.encode(value, StandardCharsets.UTF_8);
   }
 }
diff --git 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/git/GitHubRepositoryBrowser.java
 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/git/GitHubRepositoryBrowser.java
index 42650b361a..2118b1dd5b 100644
--- 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/git/GitHubRepositoryBrowser.java
+++ 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/git/GitHubRepositoryBrowser.java
@@ -26,6 +26,7 @@ import java.time.Duration;
 import java.util.ArrayList;
 import java.util.List;
 import org.apache.hop.core.exception.HopException;
+import org.apache.hop.core.util.StringUtil;
 import org.json.simple.JSONArray;
 import org.json.simple.JSONObject;
 import org.json.simple.parser.JSONParser;
@@ -49,7 +50,7 @@ class GitHubRepositoryBrowser implements GitRepositoryBrowser 
{
 
     String base =
         (apiBaseUrl != null && !apiBaseUrl.isBlank())
-            ? apiBaseUrl.replaceAll("/+$", "")
+            ? StringUtil.trimEnd(apiBaseUrl, '/')
             : DEFAULT_API;
     String url =
         base
diff --git 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/git/GitLabRepositoryBrowser.java
 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/git/GitLabRepositoryBrowser.java
index aa49a07467..124367310b 100644
--- 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/git/GitLabRepositoryBrowser.java
+++ 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/git/GitLabRepositoryBrowser.java
@@ -22,10 +22,12 @@ import java.net.URI;
 import java.net.http.HttpClient;
 import java.net.http.HttpRequest;
 import java.net.http.HttpResponse;
+import java.nio.charset.StandardCharsets;
 import java.time.Duration;
 import java.util.ArrayList;
 import java.util.List;
 import org.apache.hop.core.exception.HopException;
+import org.apache.hop.core.util.StringUtil;
 import org.json.simple.JSONArray;
 import org.json.simple.JSONObject;
 import org.json.simple.parser.JSONParser;
@@ -49,7 +51,7 @@ class GitLabRepositoryBrowser implements GitRepositoryBrowser 
{
 
     String base =
         (apiBaseUrl != null && !apiBaseUrl.isBlank())
-            ? apiBaseUrl.replaceAll("/+$", "")
+            ? StringUtil.trimEnd(apiBaseUrl, '/')
             : DEFAULT_API;
 
     StringBuilder url =
@@ -61,11 +63,8 @@ class GitLabRepositoryBrowser implements 
GitRepositoryBrowser {
             .append(page);
 
     if (searchQuery != null && !searchQuery.isBlank()) {
-      try {
-        url.append("&search=").append(java.net.URLEncoder.encode(searchQuery, 
"UTF-8"));
-      } catch (java.io.UnsupportedEncodingException e) {
-        // UTF-8 is always supported
-      }
+      url.append("&search=")
+          .append(java.net.URLEncoder.encode(searchQuery, 
StandardCharsets.UTF_8));
     }
 
     HttpRequest.Builder requestBuilder =
diff --git 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/gui/SelectRepositoryDialog.java
 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/gui/SelectRepositoryDialog.java
index 759f52adc8..0a28a3935d 100644
--- 
a/plugins/misc/projects/src/main/java/org/apache/hop/projects/gui/SelectRepositoryDialog.java
+++ 
b/plugins/misc/projects/src/main/java/org/apache/hop/projects/gui/SelectRepositoryDialog.java
@@ -19,6 +19,8 @@ package org.apache.hop.projects.gui;
 
 import java.util.ArrayList;
 import java.util.List;
+import lombok.Getter;
+import org.apache.hop.core.util.StringUtil;
 import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.projects.git.GitRepoAuth;
 import org.apache.hop.projects.git.GitRepoProvider;
@@ -87,7 +89,7 @@ public class SelectRepositoryDialog extends Dialog {
   private String selectedCloneUrl;
 
   /** The name of the selected repository, or {@code null} if cancelled. */
-  private String selectedRepoName;
+  @Getter private String selectedRepoName;
 
   private final List<GitRepositoryInfo> loadedRepos = new ArrayList<>();
   private int currentPage = 1;
@@ -315,11 +317,7 @@ public class SelectRepositoryDialog extends Dialog {
     wRepoTable.setLayoutData(fdTable);
 
     // Single click selects; double click selects and closes
-    wRepoTable.addListener(
-        SWT.Selection,
-        e -> {
-          wOk.setEnabled(wRepoTable.getSelectionCount() > 0);
-        });
+    wRepoTable.addListener(SWT.Selection, e -> 
wOk.setEnabled(wRepoTable.getSelectionCount() > 0));
     wRepoTable.addListener(SWT.DefaultSelection, e -> ok());
 
     // --- Load more button ---
@@ -347,11 +345,6 @@ public class SelectRepositoryDialog extends Dialog {
     return selectedCloneUrl;
   }
 
-  /** Returns the repo name of the last selection. */
-  public String getSelectedRepoName() {
-    return selectedRepoName;
-  }
-
   // 
---------------------------------------------------------------------------
   // UI helpers
   // 
---------------------------------------------------------------------------
@@ -503,14 +496,14 @@ public class SelectRepositoryDialog extends Dialog {
     return switch (provider) {
       case GITHUB_ENTERPRISE -> {
         if (!hostValue.isEmpty()) {
-          String base = hostValue.replaceAll("/+$", "");
+          String base = StringUtil.trimEnd(hostValue, '/');
           yield base + "/api/v3";
         }
         yield null;
       }
       case GITLAB -> {
         if (!hostValue.isEmpty()) {
-          String base = hostValue.replaceAll("/+$", "");
+          String base = StringUtil.trimEnd(hostValue, '/');
           yield base + "/api/v4";
         }
         yield null; // default to gitlab.com

Reply via email to