34 lines
1.3 KiB
Diff
34 lines
1.3 KiB
Diff
# UNDF: UNDF-2026-000000737
|
||
--- a/src/server/acl/acl_commands_def.h
|
||
+++ b/src/server/acl/acl_commands_def.h
|
||
@@ -89,7 +89,8 @@ using GlobTypePubSub = std::pair<std::string, bool>;
|
||
struct AclPubSub {
|
||
- std::vector<GlobTypePubSub> globs; // O(G) scan per channel arg — defect
|
||
+ std::vector<GlobTypePubSub> globs; // kept for glob patterns only
|
||
+ absl::flat_hash_set<std::string> exact_channels; // O(1) for literal channel names
|
||
|
||
--- a/src/server/acl/validator.cc
|
||
+++ b/src/server/acl/validator.cc
|
||
@@ -42,9 +42,18 @@ IsPubSubCommandAuthorized(...) {
|
||
auto iterate_globs = [&](std::string_view target) {
|
||
+ /* Exact-channel set check — O(1) */
|
||
+ if (pub_sub.exact_channels.contains(std::string(target))) {
|
||
+ return true;
|
||
+ }
|
||
+ /* Glob scan — only for patterns with wildcard chars; typically small or empty */
|
||
for (auto& [glob, has_asterisk] : pub_sub.globs) {
|
||
if (literal_match && (glob == target)) {
|
||
return true;
|
||
}
|
||
if (!literal_match && Matches(glob, target)) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
|
||
/* Build logic (ACL SETUSER &pattern parsing):
|
||
* - If pattern has no glob chars: insert into exact_channels — O(1) lookup
|
||
* - If pattern has glob chars: append to globs — O(G) Matches() scan
|
||
* Reduces common case (literal channel ACLs) from O(A×G) to O(A).
|
||
*/
|