util: LineReader - Drop support for raw std::byte spans
What changed, and why it matters
This commit is a small internal code cleanup in Bitcoin Core. It removes the ability of a utility called LineReader to accept raw byte buffers, and updates two network components (Tor control connection and HTTP server) to use ordinary std::string buffers instead. There is no indication in the commit that this fixes a security vulnerability; it appears to be a refactoring to simplify the code and make buffer handling more consistent.
No immediate security action required. Treat as routine refactoring. If reviewing for defense in depth, verify that the std::string receive buffers are not accidentally relying on null-termination for length, since std::string can contain embedded nulls; however, the diff shows no such issue.
Security signals we found
No security-relevant keywords in commit title or message
No CVE, advisory, or bug bounty reference in commit
Change is a type refactor (std::byte -> char/std::string) rather than a bounds-check or validation fix
Removed reinterpret_cast<const char*> path in LineReader constructor
No functional change to buffer sizes or parsing limits
Evidence from the diff
The patch removes the std::span
Changed components
src/util/string.h (LineReader utility)src/httpserver.cpp / src/httpserver.h (HTTP server receive buffer)src/torcontrol.cpp / src/torcontrol.h (Tor control receive buffer)src/test/fuzz/http_request.cpp (fuzz target input generation)Inspect captured patch +5 / −7
diff --git a/src/httpserver.cpp b/src/httpserver.cpp
index a05d19db..d7193f06 100644
--- a/src/httpserver.cpp
+++ b/src/httpserver.cpp
@@ -861,7 +861,7 @@ void HTTPServer::SocketHandlerConnected(const IOReadiness& io_readiness) const
}
if (recv_ready || err_ready) {
- std::byte buf[0x10000]; // typical socket buffer is 8K-64K
+ char buf[0x10000]; // typical socket buffer is 8K-64K
const ssize_t nrecv{WITH_LOCK(
client->m_sock_mutex,
diff --git a/src/httpserver.h b/src/httpserver.h
index 9031eb61..91142aa2 100644
--- a/src/httpserver.h
+++ b/src/httpserver.h
@@ -461,7 +461,7 @@ public:
* we copy data from the socket buffer to the client object
* and attempt to read HTTP requests from here.
*/
- std::vector<std::byte> m_recv_buffer{};
+ std::string m_recv_buffer{};
//! Requests from a client must be processed in the order in which
//! they were received, blocking on a per-client basis. We won't
diff --git a/src/test/fuzz/http_request.cpp b/src/test/fuzz/http_request.cpp
index c992edcd..82b270bd 100644
--- a/src/test/fuzz/http_request.cpp
+++ b/src/test/fuzz/http_request.cpp
@@ -25,7 +25,7 @@ FUZZ_TARGET(http_request)
using util::LineReader;
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
- const std::vector<std::byte> http_buffer{ConsumeRandomLengthByteVector<std::byte>(fuzzed_data_provider, 4096)};
+ const std::string http_buffer{fuzzed_data_provider.ConsumeRandomLengthString(4096)};
HTTPRequest http_request;
LineReader reader(http_buffer, MAX_HEADERS_SIZE);
diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp
index 9e00c715..6f05ea4b 100644
--- a/src/torcontrol.cpp
+++ b/src/torcontrol.cpp
@@ -149,7 +149,7 @@ bool TorControlConnection::ReceiveAndProcess()
{
if (!m_sock) return false;
- std::byte buf[4096];
+ char buf[4096];
ssize_t nread = m_sock->Recv(buf, sizeof(buf), MSG_DONTWAIT);
if (nread < 0) {
diff --git a/src/torcontrol.h b/src/torcontrol.h
index 410cb0b3..06a9d3e8 100644
--- a/src/torcontrol.h
+++ b/src/torcontrol.h
@@ -109,7 +109,7 @@ private:
/** Response handlers */
std::deque<ReplyHandlerCB> m_reply_handlers;
/** Buffer for incoming data */
- std::vector<std::byte> m_recv_buffer;
+ std::string m_recv_buffer;
/** Process complete lines from the receive buffer */
bool ProcessBuffer();
};
diff --git a/src/util/string.h b/src/util/string.h
index e8f6ddf8..d60fff04 100644
--- a/src/util/string.h
+++ b/src/util/string.h
@@ -272,8 +272,6 @@ class LineReader
std::string_view::iterator m_it;
public:
- explicit LineReader(std::span<const std::byte> buffer, size_t max_line_length)
- : LineReader{std::string_view{reinterpret_cast<const char*>(buffer.data()), buffer.size()}, max_line_length} {}
explicit LineReader(std::string_view str, size_t max_line_length);
/**
Why this scored 12/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.