From c7fe8501d85acf46e512dbb1cf3021673e14c17c Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Sat, 11 Apr 2026 07:55:16 +0100 Subject: [PATCH] [Fix] Use string_view::data() instead of begin() for pointer access Fixes #5969 - libc++ may return __wrap_iter from string_view::begin() instead of a raw const char *, breaking builds with libc++ 22 on FreeBSD. Use .data() where a const char * is needed and rewrite string_split_on to use find/substr instead of iterators. --- src/client/rspamc.cxx | 2 +- src/libserver/css/css_util.cxx | 2 +- src/libserver/html/html_url.cxx | 4 ++-- src/libutil/cxx/util.hxx | 15 +++++++-------- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/client/rspamc.cxx b/src/client/rspamc.cxx index 9ddb1806f8..b7cffdf4ae 100644 --- a/src/client/rspamc.cxx +++ b/src/client/rspamc.cxx @@ -649,7 +649,7 @@ rspamc_password_callback(const char *option_name, value_view = std::string_view{map, locked_mmap->get_size()}; auto right = value_view.end() - 1; for (; right > value_view.cbegin() && g_ascii_isspace(*right); --right); - std::string_view str{value_view.begin(), static_cast(right - value_view.begin()) + 1}; + std::string_view str{value_view.data(), static_cast(right - value_view.begin()) + 1}; processed_passwd.assign(std::begin(str), std::end(str)); processed_passwd.push_back('\0'); /* Null-terminate for C part */ } diff --git a/src/libserver/css/css_util.cxx b/src/libserver/css/css_util.cxx index 5a34250a0c..e23d36bdc6 100644 --- a/src/libserver/css/css_util.cxx +++ b/src/libserver/css/css_util.cxx @@ -147,7 +147,7 @@ const char *rspamd_css_unescape(rspamd_mempool_t *pool, gsize *outlen) { auto sv = rspamd::css::unescape_css(pool, {(const char *) begin, len}); - const auto *v = sv.begin(); + const auto *v = sv.data(); if (outlen) { *outlen = sv.size(); diff --git a/src/libserver/html/html_url.cxx b/src/libserver/html/html_url.cxx index 7598a01326..2c80068801 100644 --- a/src/libserver/html/html_url.cxx +++ b/src/libserver/html/html_url.cxx @@ -205,8 +205,8 @@ auto html_url_is_phished(rspamd_mempool_t *pool, */ gboolean obfuscation_found = FALSE; - if (text_data.size() > 4 && g_ascii_strncasecmp(text_data.begin(), "http", 4) == 0 && - rspamd_substring_search(text_data.begin(), text_data.size(), "://", 3) != -1) { + if (text_data.size() > 4 && g_ascii_strncasecmp(text_data.data(), "http", 4) == 0 && + rspamd_substring_search(text_data.data(), text_data.size(), "://", 3) != -1) { /* Clearly an obfuscation attempt */ obfuscation_found = TRUE; } diff --git a/src/libutil/cxx/util.hxx b/src/libutil/cxx/util.hxx index 32ec0b55c3..930164d5ad 100644 --- a/src/libutil/cxx/util.hxx +++ b/src/libutil/cxx/util.hxx @@ -144,19 +144,18 @@ inline auto string_foreach_delim(const S &input, const D &delim, const F &functo template, bool> = true> inline auto string_split_on(const S &input, std::string_view::value_type chr) -> std::pair { - auto pos = std::find(std::begin(input), std::end(input), chr); + std::string_view sv{input}; + auto pos = sv.find(chr); - if (pos != input.end()) { - auto first = std::string_view{std::begin(input), static_cast(std::distance(std::begin(input), pos))}; - while (*pos == chr && pos != input.end()) { - ++pos; - } - auto last = std::string_view{pos, static_cast(std::distance(pos, std::end(input)))}; + if (pos != std::string_view::npos) { + auto first = sv.substr(0, pos); + auto rest = sv.find_first_not_of(chr, pos); + auto last = rest != std::string_view::npos ? sv.substr(rest) : std::string_view{}; return {first, last}; } - return {std::string_view{input}, std::string_view{}}; + return {sv, std::string_view{}}; } /** -- 2.47.3