[ https://issues.apache.org/jira/browse/ARTEMIS-4532?focusedWorklogId=901714&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-901714 ]
ASF GitHub Bot logged work on ARTEMIS-4532: ------------------------------------------- Author: ASF GitHub Bot Created on: 25/Jan/24 14:36 Start Date: 25/Jan/24 14:36 Worklog Time Spent: 10m Work Description: gemmellr commented on code in PR #4710: URL: https://github.com/apache/activemq-artemis/pull/4710#discussion_r1466468912 ########## 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: Yes I think you are right, think I misread that too and believed the loop itself was looking at the last char...so it wont throw because the loop never actually looks at the last character, just the if through the charAt(i+1). Issue Time Tracking ------------------- Worklog Id: (was: 901714) Time Spent: 3h 10m (was: 3h) > 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 10m > 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)