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

tzimanyi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-drools.git


The following commit(s) were added to refs/heads/main by this push:
     new 8ff1a10daa [kie-issues#1930] replace() and matches() functions doesn't 
work with XML Character References (#6320)
8ff1a10daa is described below

commit 8ff1a10daad519fcc7fc8d8ed61f74a352c339c3
Author: Yeser Amer <[email protected]>
AuthorDate: Wed Apr 23 12:49:46 2025 +0200

    [kie-issues#1930] replace() and matches() functions doesn't work with XML 
Character References (#6320)
---
 .../java/org/kie/dmn/feel/util/XQueryImplUtil.java | 31 +++++++++++++++++++---
 .../runtime/functions/MatchesFunctionTest.java     | 16 ++++++++++-
 .../runtime/functions/ReplaceFunctionTest.java     | 17 +++++++++++-
 .../org/kie/dmn/feel/util/XQueryImplUtilTest.java  | 19 ++++++++++++-
 4 files changed, 77 insertions(+), 6 deletions(-)

diff --git 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/XQueryImplUtil.java 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/XQueryImplUtil.java
index a3ae1c6e53..e617ae77c1 100644
--- 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/XQueryImplUtil.java
+++ 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/XQueryImplUtil.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -26,17 +26,25 @@ import net.sf.saxon.s9api.XQueryEvaluator;
 import net.sf.saxon.s9api.XQueryExecutable;
 import net.sf.saxon.s9api.SaxonApiException;
 
+import java.util.regex.Pattern;
+
 public class XQueryImplUtil {
 
+    private static final Pattern XML_CHARACTER_REFERENCES_PATTERN = 
Pattern.compile("['\"&<>]");
+
+    private XQueryImplUtil() {
+        // Util class with static methods only.
+    }
+
     public static Boolean executeMatchesFunction(String input, String pattern, 
String flags) {
         flags = flags == null ? "" : flags;
-        String xQueryExpression = String.format("matches('%s', '%s', '%s')", 
input, pattern, flags);
+        String xQueryExpression = String.format("matches('%s', '%s', '%s')", 
escapeXmlCharactersReferencesForXPath(input), 
escapeXmlCharactersReferencesForXPath(pattern), flags);
         return evaluateXQueryExpression(xQueryExpression, Boolean.class);
     }
 
     public static String executeReplaceFunction(String input, String pattern, 
String replacement, String flags) {
         flags = flags == null ? "" : flags;
-        String xQueryExpression = String.format("replace('%s', '%s', '%s', 
'%s')", input, pattern, replacement, flags);
+        String xQueryExpression = String.format("replace('%s', '%s', '%s', 
'%s')", escapeXmlCharactersReferencesForXPath(input), 
escapeXmlCharactersReferencesForXPath(pattern), 
escapeXmlCharactersReferencesForXPath(replacement), flags);
         return evaluateXQueryExpression(xQueryExpression, String.class);
     }
 
@@ -59,4 +67,21 @@ public class XQueryImplUtil {
              throw new IllegalArgumentException(e);
          }
     }
+
+    /**
+     * It replaces all the XML Character References (&, ", ', <, >) in a given 
input string with their "escaping" characters.
+     * This is required to run XPath functions containing XML Character 
References.
+     * @param input A string input representing one of the parameter of 
managed functions
+     * @return A sanitized string
+     */
+    static String escapeXmlCharactersReferencesForXPath(String input) {
+        if (input != null && 
XML_CHARACTER_REFERENCES_PATTERN.matcher(input).find()) {
+            input = input.contains("&") ? input.replace("&", "&amp;") : input;
+            input = input.contains("\"") ? input.replace("\"",  "&quot;") : 
input;
+            input = input.contains("'") ? input.replace("'",  "&apos;") : 
input;
+            input = input.contains("<") ? input.replace("<",  "&lt;") : input;
+            input = input.contains(">") ? input.replace(">",  "&gt;") : input;
+        }
+        return input;
+    }
 }
diff --git 
a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/MatchesFunctionTest.java
 
b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/MatchesFunctionTest.java
index 589f37e3d2..1d63604d85 100644
--- 
a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/MatchesFunctionTest.java
+++ 
b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/MatchesFunctionTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -136,6 +136,20 @@ class MatchesFunctionTest {
         };
     }
 
+    @ParameterizedTest
+    @MethodSource("invokeWithXmlCharacterReferencesData")
+    void invokeWithXmlCharacterReferencesTest(String input, String pattern, 
Boolean expectedResult) {
+        FunctionTestUtil.assertResult(matchesFunction.invoke(input, pattern), 
expectedResult);
+    }
+
+    private static Object[][] invokeWithXmlCharacterReferencesData() {
+        return new Object[][] {
+                { "t&st", "t&st", true },
+                { "a<bra>cadabra", "<bra>", true },
+                { "abracada\"bra'", "bra", true },
+        };
+    }
+
     @Test
     void invokeWithFlagDotAll() {
         FunctionTestUtil.assertResult(matchesFunction.invoke("fo\nbar", 
"fo.bar", "s"), true);
diff --git 
a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/ReplaceFunctionTest.java
 
b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/ReplaceFunctionTest.java
index 45d1334f35..57659a5956 100644
--- 
a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/ReplaceFunctionTest.java
+++ 
b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/ReplaceFunctionTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -98,6 +98,21 @@ class ReplaceFunctionTest {
         };
     }
 
+    @ParameterizedTest
+    @MethodSource("invokeWithXmlCharacterReferencesData")
+    void invokeWithXmlCharacterReferencesTest(String input, String pattern, 
String replacement, String expectedResult) {
+        FunctionTestUtil.assertResult(replaceFunction.invoke(input, pattern, 
replacement), expectedResult);
+    }
+
+    private static Object[][] invokeWithXmlCharacterReferencesData() {
+        return new Object[][] {
+                { "<'&'>", "abc", "123", "<'&'>" },
+                { "abc&123", "abc", "123", "123&123" },
+                { "abc'123", "abc'", "123", "123123" },
+                { "abc\"123", "abc\"", "123<>", "123<>123" }
+        };
+    }
+
     @Test
     void invokeInvalidRegExPattern() {
         
FunctionTestUtil.assertResultError(replaceFunction.invoke("testString", 
"(?=\\s)", "ttt"), InvalidParametersEvent.class);
diff --git 
a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/XQueryImplUtilTest.java
 
b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/XQueryImplUtilTest.java
index 6cc71d38a6..c196d33588 100644
--- 
a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/XQueryImplUtilTest.java
+++ 
b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/XQueryImplUtilTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -114,4 +114,21 @@ class XQueryImplUtilTest {
         };
     }
 
+    @ParameterizedTest
+    @MethodSource("escapeXmlCharactersReferencesForXPathTestData")
+    void escapeXmlCharactersReferencesForXPathTest(String expression, String 
expectedResult) {
+        
assertThat(XQueryImplUtil.escapeXmlCharactersReferencesForXPath(expression)).isEqualTo(expectedResult);
+    }
+
+    private static Object[][] escapeXmlCharactersReferencesForXPathTestData() {
+        return new Object[][] {
+                { null, null },
+                { "", "" },
+                { "lolASD", "lolASD" },
+                { "List<String>", "List&lt;String&gt;" },
+                { "\"Mr.Y\"", "&quot;Mr.Y&quot;" },
+                { "'<&>'", "&apos;&lt;&amp;&gt;&apos;" },
+        };
+    }
+
 }
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to