From 269a9a10304f6fb13bff27e6021b8b01204fe5e3 Mon Sep 17 00:00:00 2001 From: "epieffe.eth" Date: Sun, 29 Dec 2024 20:40:25 +0100 Subject: [PATCH] Replace regex with custom logic for MQTT topic matching --- .../internal/config/MqttConditionMatcher.java | 62 ++++++++++++++----- 1 file changed, 48 insertions(+), 14 deletions(-) diff --git a/runtime/binding-mqtt/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/internal/config/MqttConditionMatcher.java b/runtime/binding-mqtt/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/internal/config/MqttConditionMatcher.java index 4c0f368a82..96cbaab5c8 100644 --- a/runtime/binding-mqtt/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/internal/config/MqttConditionMatcher.java +++ b/runtime/binding-mqtt/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/internal/config/MqttConditionMatcher.java @@ -105,23 +105,58 @@ public boolean matchesPublish( private boolean topicMatches(String topic, String pattern, long authorization) { - for (GuardedConfig g : guarded) + int topicIndex = 0; + for (int i = 0; i < pattern.length(); ++i) { - String identity = g.identity.apply(authorization); - if (identity != null) + char patternChar = pattern.charAt(i); + if (patternChar == '#') { - pattern = pattern.replace(String.format("{guarded[%s].identity}", g.name), identity); + return true; + } + else if (patternChar == '+') + { + while (topicIndex < topic.length()) + { + if (topic.charAt(topicIndex) == '/') + { + break; + } + topicIndex++; + } + } + else + { + if (pattern.startsWith("{guarded[", i)) + { + int i2 = i + "{guarded[".length(); + GuardedConfig guardedMatch = null; + for (GuardedConfig g : guarded) + { + if (pattern.startsWith(g.name, i2)) + { + guardedMatch = g; + i2 += g.name.length(); + break; + } + } + if (guardedMatch != null && pattern.startsWith("].identity}", i2)) + { + String identity = guardedMatch.identity.apply(authorization); + if (identity != null && topic.startsWith(identity, topicIndex)) + { + i = i2 + "].identity}".length(); + topicIndex += identity.length(); + continue; + } + } + } + if (topicIndex == topic.length() || topic.charAt(topicIndex++) != patternChar) + { + return false; + } } } - return topic.matches(pattern - .replace("{", "\\{") - .replace("}", "\\}") - .replace("[", "\\[") - .replace("]", "\\]") - .replace(".", "\\.") - .replace("$", "\\$") - .replace("+", "[^/]*") - .replace("#", ".*")); + return topicIndex == topic.length(); } private static List asWildcardMatcher( @@ -137,7 +172,6 @@ private static List asWildcardMatcher( pattern = pattern + "(\\?.*)?"; } matchers.add(Pattern.compile(pattern).matcher("")); - } return matchers;