From ffefa1aa056dbdee41cf3a6ef858e6456fd1df23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Botond=20D=C3=A9nes?= Date: Thu, 12 Feb 2026 09:10:14 +0200 Subject: [PATCH] types/duration: don't assume std::string_view is null-terminated std::string_view is not guaranteed to point to null-terminated string literals, it may point to a substring of such a string or a string which is not null-terminated. cql_duration() constructor obtains data() pointer from std::string_view and creates another std::string_view from it, after some conditional pointer arithmetics. Constructing a new std::string_view from a raw pointer, without specifying its length, will lead to strlen() being called on the pointer, resulting in undefined behaviour if the string is not null-terminated. Use substr() instead of pointer arithmetics to avoid this problem altogether. boost::regex_match() invokations also use std::string_view::data(). This leads to strlen() and heap-buffer-overflow if the string is not null-terminated. Invoke the overload which takes an iterator pair instead. Not a problem on current master, as all callers pass null-terminated strings. --- types/duration.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/types/duration.cc b/types/duration.cc index 6a95353737..039e55d00f 100644 --- a/types/duration.cc +++ b/types/duration.cc @@ -301,7 +301,7 @@ std::optional parse_duration_iso8601_format(std::string_view s) { static const auto pattern = boost::regex("P((\\d+)Y)?((\\d+)M)?((\\d+)D)?(T((\\d+)H)?((\\d+)M)?((\\d+)S)?)?"); boost::cmatch match; - if (!boost::regex_match(s.data(), match, pattern)) { + if (!boost::regex_match(s.begin(), s.end(), match, pattern)) { return {}; } @@ -341,7 +341,7 @@ std::optional parse_duration_iso8601_alternative_format(std::strin static const auto pattern = boost::regex("P(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})"); boost::cmatch match; - if (!boost::regex_match(s.data(), match, pattern)) { + if (!boost::regex_match(s.begin(), s.end(), match, pattern)) { return {}; } @@ -359,7 +359,7 @@ std::optional parse_duration_iso8601_week_format(std::string_view static const auto pattern = boost::regex("P(\\d+)W"); boost::cmatch match; - if (!boost::regex_match(s.data(), match, pattern)) { + if (!boost::regex_match(s.begin(), s.end(), match, pattern)) { return {}; } @@ -395,7 +395,7 @@ cql_duration::cql_duration(std::string_view s) { const bool is_negative = (s.length() != 0) && (s[0] == '-'); // Without any sign indicator ('-'). - const auto ps = (is_negative ? s.cbegin() + 1 : s.cbegin()); + const auto ps = (is_negative ? s.substr(1) : s); const auto d = parse_duration(ps); if (!d) {