You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2025/08/20 18:50:25 UTC

(camel) branch er created (now 86946acf96e)

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

davsclaus pushed a change to branch er
in repository https://gitbox.apache.org/repos/asf/camel.git


      at 86946acf96e CAMEL-22362: camel-exec - Use quote safe arg parser

This branch includes the following new commits:

     new 86946acf96e CAMEL-22362: camel-exec - Use quote safe arg parser

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(camel) 01/01: CAMEL-22362: camel-exec - Use quote safe arg parser

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch er
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 86946acf96e76a112956d02207b3a1473741bbb7
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Aug 20 20:49:45 2025 +0200

    CAMEL-22362: camel-exec - Use quote safe arg parser
---
 .../camel/component/exec/impl/ExecParseUtils.java  | 83 +++-------------------
 .../component/exec/impl/ExecParseUtilsTest.java    | 70 +++---------------
 2 files changed, 17 insertions(+), 136 deletions(-)

diff --git a/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/ExecParseUtils.java b/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/ExecParseUtils.java
index 65bb68b8dc6..7c1f09f2aef 100644
--- a/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/ExecParseUtils.java
+++ b/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/ExecParseUtils.java
@@ -17,97 +17,30 @@
 package org.apache.camel.component.exec.impl;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.StringTokenizer;
 
+import org.apache.camel.util.StringQuoteHelper;
+
 /**
  * Utility class for parsing, used by the Camel Exec component.<br>
  * Note: the class should be dropped, when the commons-exec library implements similar functionality.
  */
 public final class ExecParseUtils {
 
-    public static final String WHITESPACE = " ";
-
-    public static final String QUOTE_CHAR = "\"";
-
     private ExecParseUtils() {
     }
 
-    /**
-     * Splits the input line string by {@link #WHITESPACE}. Supports quoting the white-spaces with a
-     * {@link #QUOTE_CHAR}. A quote itself can also be enclosed within #{@link #QUOTE_CHAR}#{@link #QUOTE_CHAR}. More
-     * than two double-quotes in a sequence is not allowed. Nested quotes are not allowed.<br>
-     * E.g. The string <code>"arg 1"  arg2<code> will return the tokens <code>arg 1</code>, <code>arg2</code><br>
-     * The string <code>""arg 1""  "arg2" arg 3<code> will return the tokens <code>"arg 1"</code> ,
-     * <code>arg2</code>,<code>arg</code> and <code>3</code> <br>
-     *
-     * @param  input the input to split.
-     * @return       a not-null list of tokens
-     */
     public static List<String> splitToWhiteSpaceSeparatedTokens(String input) {
+        List<String> answer = new ArrayList<>();
         if (input == null) {
-            return new ArrayList<>();
-        }
-        StringTokenizer tokenizer = new StringTokenizer(input.trim(), QUOTE_CHAR + WHITESPACE, true);
-        List<String> tokens = new ArrayList<>();
-
-        StringBuilder quotedText = new StringBuilder();
-
-        while (tokenizer.hasMoreTokens()) {
-            String token = tokenizer.nextToken();
-            if (QUOTE_CHAR.equals(token)) {
-                // if we have a quote, add the next tokens to the quoted text
-                // until the quoting has finished
-                quotedText.append(QUOTE_CHAR);
-                String buffer = quotedText.toString();
-                if (isSingleQuoted(buffer) || isDoubleQuoted(buffer)) {
-                    tokens.add(buffer.substring(1, buffer.length() - 1));
-                    quotedText = new StringBuilder();
-                }
-            } else if (WHITESPACE.equals(token)) {
-                // a white space, if in quote, add the white space, otherwise
-                // skip it
-                if (quotedText.length() > 0) {
-                    quotedText.append(WHITESPACE);
-                }
-            } else {
-                if (quotedText.length() > 0) {
-                    quotedText.append(token);
-                } else {
-                    tokens.add(token);
-                }
-            }
+            return answer;
         }
-        if (quotedText.length() > 0) {
-            throw new IllegalArgumentException("Invalid quoting found in args " + quotedText);
-        }
-        return tokens;
-    }
-
-    /**
-     * Tests if the input is enclosed within {@link #QUOTE_CHAR} characters
-     *
-     * @param  input a not null String
-     * @return       true if the regular expression is matched
-     */
-    protected static boolean isSingleQuoted(String input) {
-        if (input == null || input.isBlank()) {
-            return false;
-        }
-        return input.matches("(^" + QUOTE_CHAR + "{1}([^" + QUOTE_CHAR + "]+)" + QUOTE_CHAR + "{1})");
-    }
 
-    /**
-     * Tests if the input is enclosed within a double-{@link #QUOTE_CHAR} string
-     *
-     * @param  input a not null String
-     * @return       true if the regular expression is matched
-     */
-    protected static boolean isDoubleQuoted(String input) {
-        if (input == null || input.isBlank()) {
-            return false;
-        }
-        return input.matches("(^" + QUOTE_CHAR + "{2}([^" + QUOTE_CHAR + "]+)" + QUOTE_CHAR + "{2})");
+        String[] arr = StringQuoteHelper.splitSafeQuote(input, ' ', true, false);
+        Collections.addAll(answer, arr);
+        return answer;
     }
 
     public static List<Integer> splitCommaSeparatedToListOfInts(String commaSeparatedInts) {
diff --git a/components/camel-exec/src/test/java/org/apache/camel/component/exec/impl/ExecParseUtilsTest.java b/components/camel-exec/src/test/java/org/apache/camel/component/exec/impl/ExecParseUtilsTest.java
index 9e78e9018d9..9070f41ba7f 100644
--- a/components/camel-exec/src/test/java/org/apache/camel/component/exec/impl/ExecParseUtilsTest.java
+++ b/components/camel-exec/src/test/java/org/apache/camel/component/exec/impl/ExecParseUtilsTest.java
@@ -20,64 +20,14 @@ import java.util.List;
 
 import org.junit.jupiter.api.Test;
 
-import static org.apache.camel.component.exec.impl.ExecParseUtils.isDoubleQuoted;
-import static org.apache.camel.component.exec.impl.ExecParseUtils.isSingleQuoted;
 import static org.apache.camel.component.exec.impl.ExecParseUtils.splitToWhiteSpaceSeparatedTokens;
 import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
 
 /**
  * Tests for {@link ExecParseUtils}
  */
 public class ExecParseUtilsTest {
 
-    @Test
-    public void testSingleQuoted() {
-        assertTrue(isSingleQuoted("\"c:\\program files\\test\""));
-    }
-
-    @Test
-    public void testSingleQuoted2() {
-        assertTrue(isSingleQuoted("\"with space\""));
-    }
-
-    @Test
-    public void testSingleQuotedNegative() {
-        assertFalse(isSingleQuoted("arg 0"));
-    }
-
-    @Test
-    public void testSingleQuotedNegative2() {
-        assertFalse(isSingleQuoted("\" \" space not allowed between quotes \""));
-    }
-
-    @Test
-    public void testSingleQuotedNegative3() {
-        assertFalse(isSingleQuoted("\"\"double quoted is not single quoted\"\""));
-    }
-
-    @Test
-    public void testEmptySingleQuotedNegative() {
-        assertFalse(isSingleQuoted("\"\""));
-    }
-
-    @Test
-    public void testEmptySingleQuotedNegative2() {
-        assertFalse(isSingleQuoted("\""));
-    }
-
-    @Test
-    public void testDoubleQuoted() {
-        assertTrue(isDoubleQuoted("\"\"c:\\program files\\test\\\"\""));
-    }
-
-    @Test
-    public void testEmptyDoubleQuotedNegative() {
-        assertFalse(isDoubleQuoted("\"\"\"\""));
-    }
-
     @Test
     public void testWhiteSpaceSeparatedArgs() {
         List<String> args = splitToWhiteSpaceSeparatedTokens("arg0 arg1 arg2");
@@ -102,7 +52,7 @@ public class ExecParseUtilsTest {
     @Test
     public void testWhitespaceSeparatedArgsWithSpaces() {
         List<String> args = splitToWhiteSpaceSeparatedTokens("\"arg 0 \"   arg1 \"arg 2\"");
-        assertEquals("arg 0 ", args.get(0));
+        assertEquals("arg 0", args.get(0));
         assertEquals("arg1", args.get(1));
         assertEquals("arg 2", args.get(2));
     }
@@ -115,27 +65,25 @@ public class ExecParseUtilsTest {
 
     @Test
     public void testDoubleQuoteAndSpace() {
-        List<String> args = splitToWhiteSpaceSeparatedTokens("\"\"arg0\"\" arg1");
+        List<String> args = splitToWhiteSpaceSeparatedTokens("'\"arg0\"' arg1");
         assertEquals("\"arg0\"", args.get(0));
         assertEquals("arg1", args.get(1));
     }
 
     @Test
     public void testTwoDoubleQuotes() {
-        List<String> args = splitToWhiteSpaceSeparatedTokens("\"\"arg0\"\" \"\"arg1\"\"");
+        List<String> args = splitToWhiteSpaceSeparatedTokens("'\"arg0\"' '\"arg1\"'");
         assertEquals("\"arg0\"", args.get(0));
         assertEquals("\"arg1\"", args.get(1));
     }
 
     @Test
-    public void testWhiteSpaceSeparatedArgsNotClosed() {
-        assertThrows(IllegalArgumentException.class,
-                () -> splitToWhiteSpaceSeparatedTokens("arg 0 \" arg1 \"arg 2\""));
+    public void testRuby() {
+        List<String> args = splitToWhiteSpaceSeparatedTokens("ruby -e 'puts \"Hello, world!\"'");
+        assertEquals(3, args.size());
+        assertEquals("ruby", args.get(0));
+        assertEquals("-e", args.get(1));
+        assertEquals("puts \"Hello, world!\"", args.get(2));
     }
 
-    @Test
-    public void testInvalidQuotes() {
-        assertThrows(IllegalArgumentException.class,
-                () -> splitToWhiteSpaceSeparatedTokens("\"\"arg 0 \" arg1 \"arg 2\""));
-    }
 }