From: terencehill Date: Wed, 7 Feb 2024 21:40:06 +0000 (+0100) Subject: Fix REGISTRY_CHECK not checking all elements of a huge registry like the Notification... X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=cd0ecd4e9621ad6ee55fda908c4fb1366bae8028;p=xonotic%2Fxonotic-data.pk3dir.git Fix REGISTRY_CHECK not checking all elements of a huge registry like the Notifications registry Code is optimized to have basically the same performance as before while adding string length checks. --- diff --git a/qcsrc/lib/registry.qh b/qcsrc/lib/registry.qh index fdcc730a0..5d36e1a39 100644 --- a/qcsrc/lib/registry.qh +++ b/qcsrc/lib/registry.qh @@ -177,8 +177,25 @@ void Registry_send(string id, string hash); STATIC_INIT(Registry_check_##id) \ { \ /* Note: SHA256 isn't always available, use MD4 instead */ \ - string s = ""; \ - FOREACH(id, true, s = strcat(s, ":", it.registered_id)); \ + string s = "", group = ""; \ + int str_len = 0, digests_len = 0, group_idx = 0; \ + FOREACH(id, true, { \ + group = strcat(group, ":", it.registered_id); \ + if (++group_idx < 50) /* this is to reduce strlen calls */ \ + continue; \ + int group_len = strlen(group); \ + if (str_len + 1 + group_len >= 16383) /* exceeding max string length? */ \ + { \ + /* keep previous digests and replace current string with its digest */ \ + s = strcat(substring(s, 0, digests_len), ":", digest_hex("MD4", s)); \ + digests_len = str_len = strlen(s); \ + } \ + s = strcat(s, group); \ + str_len += group_len; \ + group = ""; \ + group_idx = 0; \ + }); \ + s = strcat(s, group); \ s = substring(s, 1, -1); /* remove initial ":" */ \ string h = REGISTRY_HASH(id) = strzone(digest_hex("MD4", s)); \ LOG_DEBUGF(#id ": %s\n[%s]", h, s); \