mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-09-12 05:32:22 +02:00
Merge bitcoin/bitcoin#36164: util: diagnose dangling views of temporary strings
b57b0dbebdutil: annotate `Split` input lifetime (Lőrinc)34c5dc0583util: annotate string view input lifetimes (Lőrinc) Pull request description: **Problem:** Several string utilities return or store views into their input. A temporary `std::string` can leave these views dangling, although no current caller does this. **Fix:** Add `LIFETIMEBOUND` so Clang diagnoses the misuse while preserving immediate use. Pass the `Split` span by value so lvalue strings do not trigger false warnings. ACKs for top commit: kevkevinpal: crACKb57b0dbstickies-v: ACKb57b0dbebdhodlinator: ACKb57b0dbebdsedited: ACKb57b0dbebdTree-SHA512: 892b4c386d19dd9d46b36223084751d4be370bc985ad83283f3a2bffdd3a19f95ad107f1bf7ee4a85f90129b29553175b4713eb1308ee5176dbfa64ecff7e435
This commit is contained in:
@@ -117,7 +117,7 @@ void ReplaceAll(std::string& in_out, std::string_view search, std::string_view s
|
||||
* - 3)
|
||||
*/
|
||||
template <typename T = std::span<const char>>
|
||||
std::vector<T> Split(const std::span<const char>& sp, std::string_view separators, bool include_sep = false)
|
||||
std::vector<T> Split(std::span<const char> sp LIFETIMEBOUND, std::string_view separators, bool include_sep = false)
|
||||
{
|
||||
std::vector<T> ret;
|
||||
auto it = sp.begin();
|
||||
@@ -145,7 +145,7 @@ std::vector<T> Split(const std::span<const char>& sp, std::string_view separator
|
||||
* "foo(bar(1),2),3) on ',' will return {"foo(bar(1)", "2)", "3)"}.
|
||||
*/
|
||||
template <typename T = std::span<const char>>
|
||||
std::vector<T> Split(const std::span<const char>& sp, char sep, bool include_sep = false)
|
||||
std::vector<T> Split(std::span<const char> sp LIFETIMEBOUND, char sep, bool include_sep = false)
|
||||
{
|
||||
return Split<T>(sp, std::string_view{&sep, 1}, include_sep);
|
||||
}
|
||||
@@ -160,7 +160,7 @@ std::vector<T> Split(const std::span<const char>& sp, char sep, bool include_sep
|
||||
return Split<std::string>(str, separators);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline std::string_view TrimStringView(std::string_view str, std::string_view pattern = " \f\n\r\t\v")
|
||||
[[nodiscard]] inline std::string_view TrimStringView(std::string_view str LIFETIMEBOUND, std::string_view pattern = " \f\n\r\t\v")
|
||||
{
|
||||
std::string::size_type front = str.find_first_not_of(pattern);
|
||||
if (front == std::string::npos) {
|
||||
@@ -175,7 +175,7 @@ std::vector<T> Split(const std::span<const char>& sp, char sep, bool include_sep
|
||||
return std::string(TrimStringView(str, pattern));
|
||||
}
|
||||
|
||||
[[nodiscard]] inline std::string_view RemoveSuffixView(std::string_view str, std::string_view suffix)
|
||||
[[nodiscard]] inline std::string_view RemoveSuffixView(std::string_view str LIFETIMEBOUND, std::string_view suffix)
|
||||
{
|
||||
if (str.ends_with(suffix)) {
|
||||
return str.substr(0, str.size() - suffix.size());
|
||||
@@ -183,7 +183,7 @@ std::vector<T> Split(const std::span<const char>& sp, char sep, bool include_sep
|
||||
return str;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline std::string_view RemovePrefixView(std::string_view str, std::string_view prefix)
|
||||
[[nodiscard]] inline std::string_view RemovePrefixView(std::string_view str LIFETIMEBOUND, std::string_view prefix)
|
||||
{
|
||||
if (str.starts_with(prefix)) {
|
||||
return str.substr(prefix.size());
|
||||
@@ -273,7 +273,7 @@ class LineReader
|
||||
std::string_view::iterator m_it;
|
||||
|
||||
public:
|
||||
explicit LineReader(std::string_view str, size_t max_line_length);
|
||||
explicit LineReader(std::string_view str LIFETIMEBOUND, size_t max_line_length);
|
||||
|
||||
/**
|
||||
* Returns a string from current iterator position up to (but not including) next \n
|
||||
|
||||
Reference in New Issue
Block a user