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

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


The following commit(s) were added to refs/heads/main by this push:
     new e0fe281360 Core: fix propertiesWithPrefix to strip prefix literally, 
not as regex (#15558)
e0fe281360 is described below

commit e0fe281360281c0a9247858ca57e8b1099807718
Author: Noritaka Sekiyama <[email protected]>
AuthorDate: Wed Mar 18 15:22:54 2026 +0800

    Core: fix propertiesWithPrefix to strip prefix literally, not as regex 
(#15558)
---
 .../java/org/apache/iceberg/util/PropertyUtil.java |  2 +-
 .../org/apache/iceberg/util/TestPropertyUtil.java  | 24 ++++++++++++++++++++++
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/core/src/main/java/org/apache/iceberg/util/PropertyUtil.java 
b/core/src/main/java/org/apache/iceberg/util/PropertyUtil.java
index 0498a34a0b..b82e5ed275 100644
--- a/core/src/main/java/org/apache/iceberg/util/PropertyUtil.java
+++ b/core/src/main/java/org/apache/iceberg/util/PropertyUtil.java
@@ -168,7 +168,7 @@ public class PropertyUtil {
 
     return properties.entrySet().stream()
         .filter(e -> e.getKey().startsWith(prefix))
-        .collect(Collectors.toMap(e -> e.getKey().replaceFirst(prefix, ""), 
Map.Entry::getValue));
+        .collect(Collectors.toMap(e -> e.getKey().substring(prefix.length()), 
Map.Entry::getValue));
   }
 
   /**
diff --git a/core/src/test/java/org/apache/iceberg/util/TestPropertyUtil.java 
b/core/src/test/java/org/apache/iceberg/util/TestPropertyUtil.java
index 91c6759a3c..3925b38a59 100644
--- a/core/src/test/java/org/apache/iceberg/util/TestPropertyUtil.java
+++ b/core/src/test/java/org/apache/iceberg/util/TestPropertyUtil.java
@@ -25,6 +25,30 @@ import org.junit.jupiter.api.Test;
 
 public class TestPropertyUtil {
 
+  @Test
+  void propertiesWithPrefixHandlesRegexSpecialChars() {
+    // prefix[0]. is a valid regex where [0] matches char '0' and . matches 
any char,
+    // so replaceFirst (used by the older propertiesWithPrefix) would silently 
fail to strip the
+    // literal prefix "prefix[0]."
+    Map<String, String> properties = Map.of("prefix[0].key", "value");
+
+    Map<String, String> result = PropertyUtil.propertiesWithPrefix(properties, 
"prefix[0].");
+
+    assertThat(result).containsExactly(Map.entry("key", "value"));
+  }
+
+  @Test
+  void propertiesWithPrefixHandlesUnclosedRegexChars() {
+    // prefix[0. contains an unclosed character class which would cause
+    // PatternSyntaxException with replaceFirst (used by the older 
propertiesWithPrefix) but works
+    // correctly with substring
+    Map<String, String> properties = Map.of("prefix[0.key", "value");
+
+    Map<String, String> result = PropertyUtil.propertiesWithPrefix(properties, 
"prefix[0.");
+
+    assertThat(result).containsExactly(Map.entry("key", "value"));
+  }
+
   @Test
   void mergeProperties() {
     Map<String, String> properties = Map.of("k1", "v1", "k2", "v2");

Reply via email to