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.
This commit is contained in:
Botond Dénes
2026-02-12 09:10:14 +02:00
parent a9028d88b2
commit ffefa1aa05

View File

@@ -301,7 +301,7 @@ std::optional<cql_duration> 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<cql_duration> 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<cql_duration> 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) {