[ 
https://issues.apache.org/jira/browse/ARTEMIS-4532?focusedWorklogId=901532&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-901532
 ]

ASF GitHub Bot logged work on ARTEMIS-4532:
-------------------------------------------

                Author: ASF GitHub Bot
            Created on: 24/Jan/24 20:19
            Start Date: 24/Jan/24 20:19
    Worklog Time Spent: 10m 
      Work Description: jbertram commented on code in PR #4710:
URL: https://github.com/apache/activemq-artemis/pull/4710#discussion_r1465492836


##########
artemis-server/src/main/java/org/apache/activemq/artemis/core/config/WildcardConfiguration.java:
##########
@@ -119,19 +138,94 @@ public String getSingleWordString() {
       return singleWordString;
    }
 
-   public void setSingleWord(char singleWord) {
+   public WildcardConfiguration setSingleWord(char singleWord) {
       this.singleWord = singleWord;
       this.singleWordString = String.valueOf(singleWord);
+      return this;
    }
 
-   public String convert(String filter, WildcardConfiguration to) {
-      if (this.equals(to)) {
-         return filter;
+   /**
+    * Convert the input from this WildcardConfiguration into the specified 
WildcardConfiguration.
+    *
+    * If the input already contains characters defined in the target 
WildcardConfiguration then those characters will
+    * be escaped and preserved as such in the returned String. That said, 
wildcard characters which are the same
+    * between the two configurations will not be escaped
+    *
+    * If the input already contains escaped characters defined in this 
WildcardConfiguration then those characters will
+    * be unescaped after conversion and restored in the returned String.
+    *
+    * @param input  the String to convert
+    * @param target the WildcardConfiguration to convert the input into
+    * @return the converted String
+    */
+   public String convert(final String input, final WildcardConfiguration 
target) {
+      if (this.equals(target)) {
+         return input;
       } else {
-         return filter
-            .replace(getDelimiter(), to.getDelimiter())
-            .replace(getSingleWord(), to.getSingleWord())
-            .replace(getAnyWords(), to.getAnyWords());
+         boolean escaped = isEscaped(input);
+         StringBuilder result;
+         if (!escaped) {
+            result = new StringBuilder(target.escape(input, this));
+         } else {
+            result = new StringBuilder(input);
+         }
+         replaceChar(result, getDelimiter(), target.getDelimiter());
+         replaceChar(result, getSingleWord(), target.getSingleWord());
+         replaceChar(result, getAnyWords(), target.getAnyWords());
+         if (escaped) {
+            return unescape(result.toString());
+         } else {
+            return result.toString();
+         }
+      }
+   }
+
+   private String escape(final String input, WildcardConfiguration from) {
+      String result = input.replace(escapeString, escapeString + escapeString);
+      if (delimiter != from.getDelimiter()) {
+         result = result.replace(getDelimiterString(), escapeString + 
getDelimiterString());
+      }
+      if (singleWord != from.getSingleWord()) {
+         result = result.replace(getSingleWordString(), escapeString + 
getSingleWordString());
+      }
+      if (anyWords != from.getAnyWords()) {
+         result = result.replace(getAnyWordsString(), escapeString + 
getAnyWordsString());
+      }
+      return result;
+   }
+
+   private String unescape(final String input) {
+      return input
+         .replace(escapeString + escapeString, escapeString)
+         .replace(ESCAPE + getDelimiterString(), getDelimiterString())
+         .replace(ESCAPE + getSingleWordString(), getSingleWordString())
+         .replace(ESCAPE + getAnyWordsString(), getAnyWordsString());
+   }
+
+   private boolean isEscaped(final String input) {
+      for (int i = 0; i < input.length() - 1; i++) {
+         if (input.charAt(i) == ESCAPE && (input.charAt(i + 1) == 
getDelimiter() || input.charAt(i + 1) == getSingleWord() || input.charAt(i + 1) 
== getAnyWords())) {
+            return true;
+         }
+      }

Review Comment:
   I think the `i < input.length() - 1` is preventing any issue here. If it was 
using `<=` or just `input.length()` there would be a problem, but as it stands 
now you can pass a `String` where the last character is the escape character 
(e.g. `foo\\`) and there's no IOOBE.





Issue Time Tracking
-------------------

    Worklog Id:     (was: 901532)
    Time Spent: 3h  (was: 2h 50m)

> MQTT-to-core wildcard conversion is broken
> ------------------------------------------
>
>                 Key: ARTEMIS-4532
>                 URL: https://issues.apache.org/jira/browse/ARTEMIS-4532
>             Project: ActiveMQ Artemis
>          Issue Type: Bug
>            Reporter: Justin Bertram
>            Assignee: Justin Bertram
>            Priority: Major
>          Time Spent: 3h
>  Remaining Estimate: 0h
>
> Currently when an MQTT topic filter contains characters from the configured 
> [wildcard 
> syntax|https://activemq.apache.org/components/artemis/documentation/latest/wildcard-syntax.html#wildcard-syntax]
>  the conversion to/from this syntax breaks.
> For example, when using the default wildcard syntax if an MQTT topic filter 
> contains a {{.}} the conversion from the MQTT wildcard syntax to the core 
> wildcard syntax and back will result in the {{.}} being replaced with a {{/}}.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to