[ https://issues.apache.org/jira/browse/ARTEMIS-4532?focusedWorklogId=901399&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-901399 ]
ASF GitHub Bot logged work on ARTEMIS-4532: ------------------------------------------- Author: ASF GitHub Bot Created on: 24/Jan/24 10:04 Start Date: 24/Jan/24 10:04 Worklog Time Spent: 10m Work Description: gemmellr commented on code in PR #4710: URL: https://github.com/apache/activemq-artemis/pull/4710#discussion_r1464661184 ########## 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: Doesn't seem like it. That governs that the variable i cant be beyond the 0-based string index used for _charAt(i)_, but the loop then also uses _charAt(i+1)_, so for the last character that would become input.length() and be beyond the limit? Issue Time Tracking ------------------- Worklog Id: (was: 901399) Time Spent: 1h 50m (was: 1h 40m) > 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: 1h 50m > 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)