util/test: Add string_view constructor to LineReader and remove StringToBuffer
What changed, and why it matters
This is a small internal code cleanup in Bitcoin Core's test utilities. It adds a convenience constructor so a LineReader can be created directly from a string_view, and removes a helper function that was only used to convert strings into byte buffers for tests. There is no security issue here.
No action required. This is a benign refactoring/cleanup change.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit adds an explicit LineReader(std::string_view str, size_t max_line_length) constructor that delegates to the existing std::span<const std::byte> constructor via std::as_bytes(std::span{str}). It removes the test-only StringToBuffer helper and updates unit tests to use string_view literals directly. The functional behavior of LineReader is unchanged.
Changed components
src/util/string.hsrc/test/util_string_tests.cppInspect captured patch +10 / −15
diff --git a/src/test/util_string_tests.cpp b/src/test/util_string_tests.cpp
index dea45f6f..3835904d 100644
--- a/src/test/util_string_tests.cpp
+++ b/src/test/util_string_tests.cpp
@@ -42,12 +42,6 @@ void FailFmtWithError(const char* wrong_fmt, std::string_view error)
BOOST_CHECK_EXCEPTION(CheckNumFormatSpecifiers<WrongNumArgs>(wrong_fmt), const char*, HasReason{error});
}
-std::vector<std::byte> StringToBuffer(const std::string& str)
-{
- auto span = std::as_bytes(std::span(str));
- return {span.begin(), span.end()};
-}
-
BOOST_AUTO_TEST_CASE(ConstevalFormatString_NumSpec)
{
PassFmt<0>("");
@@ -181,7 +175,7 @@ BOOST_AUTO_TEST_CASE(line_reader_test)
{
{
// Check three lines terminated by \n and \r\n, trimming whitespace
- const std::vector<std::byte> input{StringToBuffer("once upon a time\n there was a dog \r\nwho liked food\n")};
+ std::string_view input = "once upon a time\n there was a dog \r\nwho liked food\n";
LineReader reader(input, /*max_line_length=*/128);
BOOST_CHECK_EQUAL(reader.Consumed(), 0);
BOOST_CHECK_EQUAL(reader.Remaining(), 51);
@@ -206,7 +200,7 @@ BOOST_AUTO_TEST_CASE(line_reader_test)
{
// Do not exceed max_line_length + 1 while searching for \n
// Test with 22-character line + \n + 23-character line + \n
- const std::vector<std::byte> input{StringToBuffer("once upon a time there\nwas a dog who liked tea\n")};
+ std::string_view input = "once upon a time there\nwas a dog who liked tea\n";
LineReader reader1(input, /*max_line_length=*/22);
// First line is exactly the length of max_line_length
@@ -224,26 +218,26 @@ BOOST_AUTO_TEST_CASE(line_reader_test)
}
{
// Empty lines are empty
- const std::vector<std::byte> input{StringToBuffer("\n")};
+ std::string_view input = "\n";
LineReader reader(input, /*max_line_length=*/1024);
BOOST_CHECK_EQUAL(reader.ReadLine(), "");
BOOST_CHECK(!reader.ReadLine());
}
{
// Empty buffers are null
- const std::vector<std::byte> input{StringToBuffer("")};
+ std::string_view input;
LineReader reader(input, /*max_line_length=*/1024);
BOOST_CHECK(!reader.ReadLine());
}
{
// Even one character is too long, if it's not \n
- const std::vector<std::byte> input{StringToBuffer("ab\n")};
+ std::string_view input = "ab\n";
LineReader reader(input, /*max_line_length=*/1);
// First line is +1 character too long
BOOST_CHECK_EXCEPTION(reader.ReadLine(), std::runtime_error, HasReason{"max_line_length exceeded by LineReader"});
}
{
- const std::vector<std::byte> input{StringToBuffer("a\nb\n")};
+ std::string_view input = "a\nb\n";
LineReader reader(input, /*max_line_length=*/1);
BOOST_CHECK_EQUAL(reader.ReadLine(), "a");
BOOST_CHECK_EQUAL(reader.ReadLine(), "b");
@@ -251,7 +245,7 @@ BOOST_AUTO_TEST_CASE(line_reader_test)
}
{
// If ReadLine fails, the iterator is reset and we can ReadLength instead
- const std::vector<std::byte> input{StringToBuffer("a\nbaboon\n")};
+ std::string_view input = "a\nbaboon\n";
LineReader reader(input, /*max_line_length=*/1);
BOOST_CHECK_EQUAL(reader.ReadLine(), "a");
// "baboon" is too long
@@ -267,7 +261,7 @@ BOOST_AUTO_TEST_CASE(line_reader_test)
}
{
// The end of the buffer (EOB) does not count as end of line \n
- const std::vector<std::byte> input{StringToBuffer("once upon a time there")};
+ std::string_view input = "once upon a time there";
LineReader reader(input, /*max_line_length=*/22);
// First line is exactly the length of max_line_length, but that doesn't matter because \n is missing
@@ -279,7 +273,7 @@ BOOST_AUTO_TEST_CASE(line_reader_test)
}
{
// Read specific number of bytes regardless of max_line_length or \n unless buffer is too short
- const std::vector<std::byte> input{StringToBuffer("once upon a time\n there was a dog \r\nwho liked food")};
+ std::string_view input = "once upon a time\n there was a dog \r\nwho liked food";
LineReader reader(input, /*max_line_length=*/1);
BOOST_CHECK_EQUAL(reader.ReadLength(0), "");
BOOST_CHECK_EQUAL(reader.ReadLength(3), "onc");
diff --git a/src/util/string.h b/src/util/string.h
index 64b49bb0..da4ce5a3 100644
--- a/src/util/string.h
+++ b/src/util/string.h
@@ -270,6 +270,7 @@ struct LineReader {
std::span<const std::byte>::iterator it;
explicit LineReader(std::span<const std::byte> buffer, size_t max_line_length);
+ explicit LineReader(std::string_view str, size_t max_line_length) : LineReader{std::as_bytes(std::span{str}), max_line_length} {}
/**
* Returns a string from current iterator position up to (but not including) next \n
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.