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

yamer 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 77cb73091a [incubator-kie-issues#1382] Fix identifier retrieval for 
quoted strings (#6021)
77cb73091a is described below

commit 77cb73091aeb7b321015b8dd3fed2d42054bb6d4
Author: Gabriele Cardosi <[email protected]>
AuthorDate: Fri Jul 12 10:09:26 2024 +0200

    [incubator-kie-issues#1382] Fix identifier retrieval for quoted strings 
(#6021)
    
    Co-authored-by: Gabriele-Cardosi <[email protected]>
---
 .../main/java/org/drools/mvel/MVELConstraint.java  |   2 +-
 .../src/main/java/org/drools/util/StringUtils.java |  22 ++++-
 .../test/java/org/drools/util/StringUtilsTest.java | 105 +++++++++++++++++++++
 3 files changed, 126 insertions(+), 3 deletions(-)

diff --git a/drools-mvel/src/main/java/org/drools/mvel/MVELConstraint.java 
b/drools-mvel/src/main/java/org/drools/mvel/MVELConstraint.java
index 515d3f1302..932c3bcde9 100644
--- a/drools-mvel/src/main/java/org/drools/mvel/MVELConstraint.java
+++ b/drools-mvel/src/main/java/org/drools/mvel/MVELConstraint.java
@@ -553,7 +553,7 @@ public class MVELConstraint extends 
MutableTypeConstraint<ContextEntry> implemen
     private int nextPropertyName(String expression, List<String> names, int 
cursor) {
         StringBuilder propertyNameBuilder = new StringBuilder();
         cursor = extractFirstIdentifier(expression, propertyNameBuilder, 
cursor);
-        if (propertyNameBuilder.length() == 0) {
+        if (propertyNameBuilder.isEmpty()) {
             return cursor;
         }
 
diff --git a/drools-util/src/main/java/org/drools/util/StringUtils.java 
b/drools-util/src/main/java/org/drools/util/StringUtils.java
index f94ce49b83..e73555c7bd 100644
--- a/drools-util/src/main/java/org/drools/util/StringUtils.java
+++ b/drools-util/src/main/java/org/drools/util/StringUtils.java
@@ -964,8 +964,23 @@ public class StringUtils {
         return builder.toString();
     }
 
+    /**
+     * Method that tries to extract <b>identifiers</b> from a Srting.
+     * First, it tries to identify "quoted" part, that should be ignored.
+     * Then, it tries to extract a String that is valid as java identifier.
+     * If an identifier is found, returns the last index of the identifier 
itself, otherwise the length of the string itself
+     *
+     * {@link Character#isJavaIdentifierStart}
+     * {@link Character#isJavaIdentifierPart}
+     * @param string
+     * @param builder
+     * @param start
+     * @return
+     */
     public static int extractFirstIdentifier(String string, StringBuilder 
builder, int start) {
         boolean isQuoted = false;
+        boolean isDoubleQuoted = false;
+        boolean isSingleQuoted = false;
         boolean started = false;
         int i = start;
         for (; i < string.length(); i++) {
@@ -973,13 +988,16 @@ public class StringUtils {
             if (!isQuoted && Character.isJavaIdentifierStart(ch)) {
                 builder.append(ch);
                 started = true;
-            } else if (ch == '"' || ch == '\'') {
-                isQuoted = !isQuoted;
+            } else if (ch == '"') {
+                isDoubleQuoted = !isQuoted && !isDoubleQuoted;
+            } else if (ch == '\'') {
+                isSingleQuoted = !isQuoted && !isSingleQuoted;
             } else if (started && Character.isJavaIdentifierPart(ch)) {
                 builder.append(ch);
             } else if (started) {
                 break;
             }
+            isQuoted = isDoubleQuoted || isSingleQuoted;
         }
         return i;
     }
diff --git a/drools-util/src/test/java/org/drools/util/StringUtilsTest.java 
b/drools-util/src/test/java/org/drools/util/StringUtilsTest.java
index 2f41589a17..7fca6c14fe 100644
--- a/drools-util/src/test/java/org/drools/util/StringUtilsTest.java
+++ b/drools-util/src/test/java/org/drools/util/StringUtilsTest.java
@@ -239,6 +239,111 @@ public class StringUtilsTest {
         assertThat(retrieved).isEqualTo(expected);
     }
 
+    @Test
+    public void testExtractFirstIdentifierWithStringBuilder() {
+        // Not-quoted string, interpreted as identifier
+        String string = "IDENTIFIER";
+        String expected = string;
+        StringBuilder builder = new StringBuilder();
+        int start = 0;
+        int retrieved = StringUtils.extractFirstIdentifier(string, builder, 
start);
+        assertThat(retrieved).isEqualTo(string.length()); // retrieved size is 
equals to the length of given string
+        assertThat(builder.toString()).isEqualTo(expected);
+
+        // Quoted string, not interpreted as identifier
+        string = "\"IDENTIFIER\"";
+        expected = "";
+        builder = new StringBuilder();
+        retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
+        assertThat(retrieved).isEqualTo(string.length());
+        assertThat(builder.toString()).isEqualTo(expected);
+
+        // Only the not-quoted string, and its size, is returned
+        string = "IDENTIFIER \"";
+        expected = "IDENTIFIER";
+        builder = new StringBuilder();
+        retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
+        assertThat(retrieved).isEqualTo(expected.length()); // it returns the 
index where the identifier ends
+        assertThat(builder.toString()).isEqualTo(expected);
+
+        string = "IDENTIFIER \"the_identifier";
+        expected = "IDENTIFIER";
+        builder = new StringBuilder();
+        retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
+        assertThat(retrieved).isEqualTo(expected.length()); // it returns the 
index where the identifier ends
+        assertThat(builder.toString()).isEqualTo(expected);
+
+        string = "\"the_identifier\" IDENTIFIER";
+        expected = "IDENTIFIER";
+        builder = new StringBuilder();
+        retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
+        assertThat(retrieved).isEqualTo(string.length()); // it returns the 
index where the identifier ends
+        assertThat(builder.toString()).isEqualTo(expected);
+
+        // Quoted string, not interpreted as identifier, starting at arbitrary 
position
+        string = "THIS IS BEFORE \"IDENTIFIER\"";
+        expected = "";
+        builder = new StringBuilder();
+        start = 14;
+        retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
+        assertThat(retrieved).isEqualTo(string.length());
+        assertThat(builder.toString()).isEqualTo(expected);
+
+        // Only the not-quoted string, and its size, is returned, starting at 
arbitrary position
+        string = "THIS IS BEFORE IDENTIFIER \"";
+        expected = "IDENTIFIER";
+        builder = new StringBuilder();
+        retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
+        assertThat(retrieved).isEqualTo(25); // it returns the index where the 
identifier ends
+        assertThat(builder.toString()).isEqualTo(expected);
+
+        string = "IDENTIFIER \"the_identifier";
+        expected = "";
+        builder = new StringBuilder();
+        start = 10;
+        retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
+        assertThat(retrieved).isEqualTo(string.length()); // it returns the 
index where the identifier ends
+        assertThat(builder.toString()).isEqualTo(expected);
+
+        string = "IDENTIFIER \"the_identifier";
+        expected = "";
+        builder = new StringBuilder();
+        start = 10;
+        retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
+        assertThat(retrieved).isEqualTo(string.length()); // it returns the 
index where the identifier ends
+        assertThat(builder.toString()).isEqualTo(expected);
+
+        string = "\"not an ' identifier\"";
+        expected = "";
+        builder = new StringBuilder();
+        start = 0;
+        retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
+        assertThat(retrieved).isEqualTo(string.length()); // it returns the 
whole string length
+        assertThat(builder.toString()).isEqualTo(expected);
+
+        string = "'not an \" identifier'";
+        expected = "";
+        builder = new StringBuilder();
+        retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
+        assertThat(retrieved).isEqualTo(string.length()); // it returns the 
whole string length
+        assertThat(builder.toString()).isEqualTo(expected);
+
+        string = "'not an \" identifier\"'";
+        expected = "";
+        builder = new StringBuilder();
+        retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
+        assertThat(retrieved).isEqualTo(string.length()); // it returns the 
whole string length
+        assertThat(builder.toString()).isEqualTo(expected);
+
+        string = "\"an \" IDENTIFIER";
+        expected = "IDENTIFIER";
+        builder = new StringBuilder();
+        retrieved = StringUtils.extractFirstIdentifier(string, builder, start);
+        assertThat(retrieved).isEqualTo(string.length()); // it returns the 
index where the identifier ends
+        assertThat(builder.toString()).isEqualTo(expected);
+
+    }
+
     @Test
     public void testSplitStatements() {
         String text =


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

Reply via email to