Skip to content

Commit 4c166e1

Browse files
Merge #6531: backport: finish merging 25001
e714607 Merge bitcoin#25001: Modernize util/strencodings and util/string (pasta) f6bd506 rename: ValidAsCString -> ContainsNoNUL (pasta) 0ce624f Use std::string_view throughout util strencodings/string (Pieter Wuille) 5271cfa fix: DecodeBase64 changes in dash code (pasta) b6122ea Make DecodeBase{32,64} take string_view arguments (Pieter Wuille) 7e5c0b5 Generalize ConvertBits to permit transforming the input (Pieter Wuille) 9519ace Make DecodeBase{32,64} return optional instead of taking bool* (Pieter Wuille) 765ec3f Make DecodeBase{32,64} always return vector, not string (Pieter Wuille) Pull request description: ## Issue being fixed or feature implemented This was partially done earlier; do the remaining commits ## What was done? see commits ## How Has This Been Tested? built locally ## Breaking Changes none ## Checklist: _Go over all the following points, and put an `x` in all the boxes that apply._ - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have made corresponding changes to the documentation - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ ACKs for top commit: UdjinM6: utACK e714607 Tree-SHA512: e65c347a551c30b04f398ecd2d45388cbc04374a035726be35138dbd39d4921162ecee440056acd13d83aeec1b15ba6db6744c0de62a725859de0177f7c5f3ef
2 parents 80cd18e + e714607 commit 4c166e1

26 files changed

+198
-234
lines changed

src/base58.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ std::string EncodeBase58(Span<const unsigned char> input)
126126

127127
bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet, int max_ret_len)
128128
{
129-
if (!ValidAsCString(str)) {
129+
if (!ContainsNoNUL(str)) {
130130
return false;
131131
}
132132
return DecodeBase58(str.c_str(), vchRet, max_ret_len);
@@ -160,7 +160,7 @@ std::string EncodeBase58Check(Span<const unsigned char> input)
160160

161161
bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet, int max_ret)
162162
{
163-
if (!ValidAsCString(str)) {
163+
if (!ContainsNoNUL(str)) {
164164
return false;
165165
}
166166
return DecodeBase58Check(str.c_str(), vchRet, max_ret);

src/bitcoin-tx.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ static void MutateTxLocktime(CMutableTransaction& tx, const std::string& cmdVal)
223223
template <typename T>
224224
static T TrimAndParse(const std::string& int_str, const std::string& err)
225225
{
226-
const auto parsed{ToIntegral<T>(TrimString(int_str))};
226+
const auto parsed{ToIntegral<T>(TrimStringView(int_str))};
227227
if (!parsed.has_value()) {
228228
throw std::runtime_error(err + " '" + int_str + "'");
229229
}

src/httprpc.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,11 @@ static bool RPCAuthorized(const std::string& strAuth, std::string& strAuthUserna
171171
return false;
172172
if (strAuth.substr(0, 6) != "Basic ")
173173
return false;
174-
std::string strUserPass64 = TrimString(strAuth.substr(6));
175-
bool invalid;
176-
std::string strUserPass = DecodeBase64(strUserPass64, &invalid);
177-
if (invalid) return false;
174+
std::string_view strUserPass64 = TrimStringView(std::string_view{strAuth}.substr(6));
175+
auto userpass_data = DecodeBase64(strUserPass64);
176+
std::string strUserPass;
177+
if (!userpass_data) return false;
178+
strUserPass.assign(userpass_data->begin(), userpass_data->end());
178179

179180
if (strUserPass.find(':') != std::string::npos)
180181
strAuthUsernameOut = strUserPass.substr(0, strUserPass.find(':'));

src/httpserver.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -272,12 +272,11 @@ static void http_request_cb(struct evhttp_request* req, void* arg)
272272
return false;
273273

274274
std::string strUserPass64 = TrimString(strAuth.substr(6));
275-
bool invalid;
276-
std::string strUserPass = DecodeBase64(strUserPass64, &invalid);
277-
if (invalid) return false;
278-
279-
if (strUserPass.find(':') == std::string::npos) return false;
280-
const std::string username{strUserPass.substr(0, strUserPass.find(':'))};
275+
auto opt_strUserPass = DecodeBase64(strUserPass64);
276+
if (!opt_strUserPass.has_value()) return false;
277+
auto it = std::find(opt_strUserPass->begin(), opt_strUserPass->end(), ':');
278+
if (it == opt_strUserPass->end()) return false;
279+
const std::string username = std::string(opt_strUserPass->begin(), it);
281280
return find(g_external_usernames.begin(), g_external_usernames.end(), username) != g_external_usernames.end();
282281
}();
283282

src/i2p.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,11 @@ static std::string SwapBase64(const std::string& from)
6969
static Binary DecodeI2PBase64(const std::string& i2p_b64)
7070
{
7171
const std::string& std_b64 = SwapBase64(i2p_b64);
72-
bool invalid;
73-
Binary decoded = DecodeBase64(std_b64.c_str(), &invalid);
74-
if (invalid) {
72+
auto decoded = DecodeBase64(std_b64);
73+
if (!decoded) {
7574
throw std::runtime_error(strprintf("Cannot decode Base64: \"%s\"", i2p_b64));
7675
}
77-
return decoded;
76+
return std::move(*decoded);
7877
}
7978

8079
/**

src/netaddress.cpp

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ static void Checksum(Span<const uint8_t> addr_pubkey, uint8_t (&checksum)[CHECKS
211211

212212
bool CNetAddr::SetSpecial(const std::string& addr)
213213
{
214-
if (!ValidAsCString(addr)) {
214+
if (!ContainsNoNUL(addr)) {
215215
return false;
216216
}
217217

@@ -235,17 +235,16 @@ bool CNetAddr::SetTor(const std::string& addr)
235235
return false;
236236
}
237237

238-
bool invalid;
239-
const auto& input = DecodeBase32(addr.substr(0, addr.size() - suffix_len).c_str(), &invalid);
238+
auto input = DecodeBase32(std::string_view{addr}.substr(0, addr.size() - suffix_len));
240239

241-
if (invalid) {
240+
if (!input) {
242241
return false;
243242
}
244243

245-
if (input.size() == torv3::TOTAL_LEN) {
246-
Span<const uint8_t> input_pubkey{input.data(), ADDR_TORV3_SIZE};
247-
Span<const uint8_t> input_checksum{input.data() + ADDR_TORV3_SIZE, torv3::CHECKSUM_LEN};
248-
Span<const uint8_t> input_version{input.data() + ADDR_TORV3_SIZE + torv3::CHECKSUM_LEN, sizeof(torv3::VERSION)};
244+
if (input->size() == torv3::TOTAL_LEN) {
245+
Span<const uint8_t> input_pubkey{input->data(), ADDR_TORV3_SIZE};
246+
Span<const uint8_t> input_checksum{input->data() + ADDR_TORV3_SIZE, torv3::CHECKSUM_LEN};
247+
Span<const uint8_t> input_version{input->data() + ADDR_TORV3_SIZE + torv3::CHECKSUM_LEN, sizeof(torv3::VERSION)};
249248

250249
if (input_version != torv3::VERSION) {
251250
return false;
@@ -281,15 +280,14 @@ bool CNetAddr::SetI2P(const std::string& addr)
281280
// can decode it.
282281
const std::string b32_padded = addr.substr(0, b32_len) + "====";
283282

284-
bool invalid;
285-
const auto& address_bytes = DecodeBase32(b32_padded.c_str(), &invalid);
283+
auto address_bytes = DecodeBase32(b32_padded);
286284

287-
if (invalid || address_bytes.size() != ADDR_I2P_SIZE) {
285+
if (!address_bytes || address_bytes->size() != ADDR_I2P_SIZE) {
288286
return false;
289287
}
290288

291289
m_net = NET_I2P;
292-
m_addr.assign(address_bytes.begin(), address_bytes.end());
290+
m_addr.assign(address_bytes->begin(), address_bytes->end());
293291

294292
return true;
295293
}

src/netbase.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ std::vector<std::string> GetNetworkNames(bool append_unroutable)
144144

145145
static std::vector<CNetAddr> LookupIntern(const std::string& name, unsigned int nMaxSolutions, bool fAllowLookup, DNSLookupFn dns_lookup_function)
146146
{
147-
if (!ValidAsCString(name)) return {};
147+
if (!ContainsNoNUL(name)) return {};
148148
{
149149
CNetAddr addr;
150150
// From our perspective, onion addresses are not hostnames but rather
@@ -173,7 +173,7 @@ static std::vector<CNetAddr> LookupIntern(const std::string& name, unsigned int
173173

174174
std::vector<CNetAddr> LookupHost(const std::string& name, unsigned int nMaxSolutions, bool fAllowLookup, DNSLookupFn dns_lookup_function)
175175
{
176-
if (!ValidAsCString(name)) return {};
176+
if (!ContainsNoNUL(name)) return {};
177177
std::string strHost = name;
178178
if (strHost.empty()) return {};
179179
if (strHost.front() == '[' && strHost.back() == ']') {
@@ -191,7 +191,7 @@ std::optional<CNetAddr> LookupHost(const std::string& name, bool fAllowLookup, D
191191

192192
std::vector<CService> Lookup(const std::string& name, uint16_t portDefault, bool fAllowLookup, unsigned int nMaxSolutions, DNSLookupFn dns_lookup_function)
193193
{
194-
if (name.empty() || !ValidAsCString(name)) {
194+
if (name.empty() || !ContainsNoNUL(name)) {
195195
return {};
196196
}
197197
uint16_t port{portDefault};
@@ -216,7 +216,7 @@ std::optional<CService> Lookup(const std::string& name, uint16_t portDefault, bo
216216

217217
CService LookupNumeric(const std::string& name, uint16_t portDefault, DNSLookupFn dns_lookup_function)
218218
{
219-
if (!ValidAsCString(name)) {
219+
if (!ContainsNoNUL(name)) {
220220
return {};
221221
}
222222
// "1.2:345" will fail to resolve the ip, but will still set the port.
@@ -667,7 +667,7 @@ bool ConnectThroughProxy(const Proxy& proxy, const std::string& strDest, uint16_
667667

668668
bool LookupSubNet(const std::string& subnet_str, CSubNet& subnet_out)
669669
{
670-
if (!ValidAsCString(subnet_str)) {
670+
if (!ContainsNoNUL(subnet_str)) {
671671
return false;
672672
}
673673

src/psbt.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -343,18 +343,17 @@ std::string PSBTRoleName(PSBTRole role) {
343343

344344
bool DecodeBase64PSBT(PartiallySignedTransaction& psbt, const std::string& base64_tx, std::string& error)
345345
{
346-
bool invalid;
347-
std::string tx_data = DecodeBase64(base64_tx, &invalid);
348-
if (invalid) {
346+
auto tx_data = DecodeBase64(base64_tx);
347+
if (!tx_data) {
349348
error = "invalid base64";
350349
return false;
351350
}
352-
return DecodeRawPSBT(psbt, tx_data, error);
351+
return DecodeRawPSBT(psbt, MakeByteSpan(*tx_data), error);
353352
}
354353

355-
bool DecodeRawPSBT(PartiallySignedTransaction& psbt, const std::string& tx_data, std::string& error)
354+
bool DecodeRawPSBT(PartiallySignedTransaction& psbt, Span<const std::byte> tx_data, std::string& error)
356355
{
357-
CDataStream ss_data(MakeByteSpan(tx_data), SER_NETWORK, PROTOCOL_VERSION);
356+
CDataStream ss_data(tx_data, SER_NETWORK, PROTOCOL_VERSION);
358357
try {
359358
ss_data >> psbt;
360359
if (!ss_data.empty()) {

src/psbt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,6 @@ bool FinalizeAndExtractPSBT(PartiallySignedTransaction& psbtx, CMutableTransacti
914914
//! Decode a base64ed PSBT into a PartiallySignedTransaction
915915
[[nodiscard]] bool DecodeBase64PSBT(PartiallySignedTransaction& decoded_psbt, const std::string& base64_psbt, std::string& error);
916916
//! Decode a raw (binary blob) PSBT into a PartiallySignedTransaction
917-
[[nodiscard]] bool DecodeRawPSBT(PartiallySignedTransaction& decoded_psbt, const std::string& raw_psbt, std::string& error);
917+
[[nodiscard]] bool DecodeRawPSBT(PartiallySignedTransaction& decoded_psbt, Span<const std::byte> raw_psbt, std::string& error);
918918

919919
#endif // BITCOIN_PSBT_H

src/qt/walletframe.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -249,16 +249,16 @@ void WalletFrame::gotoVerifyMessageTab(QString addr)
249249

250250
void WalletFrame::gotoLoadPSBT(bool from_clipboard)
251251
{
252-
std::string data;
252+
std::vector<unsigned char> data;
253253

254254
if (from_clipboard) {
255255
std::string raw = QApplication::clipboard()->text().toStdString();
256-
bool invalid;
257-
data = DecodeBase64(raw, &invalid);
258-
if (invalid) {
256+
auto result = DecodeBase64(raw);
257+
if (!result) {
259258
Q_EMIT message(tr("Error"), tr("Unable to decode PSBT from clipboard (invalid base64)"), CClientUIInterface::MSG_ERROR);
260259
return;
261260
}
261+
data = std::move(*result);
262262
} else {
263263
QString filename = GUIUtil::getOpenFileName(this,
264264
tr("Load Transaction Data"), QString(),
@@ -269,12 +269,12 @@ void WalletFrame::gotoLoadPSBT(bool from_clipboard)
269269
return;
270270
}
271271
std::ifstream in{filename.toLocal8Bit().data(), std::ios::binary};
272-
data = std::string(std::istreambuf_iterator<char>{in}, {});
272+
data.assign(std::istream_iterator<unsigned char>{in}, {});
273273
}
274274

275275
std::string error;
276276
PartiallySignedTransaction psbtx;
277-
if (!DecodeRawPSBT(psbtx, data, error)) {
277+
if (!DecodeRawPSBT(psbtx, MakeByteSpan(data), error)) {
278278
Q_EMIT message(tr("Error"), tr("Unable to decode PSBT") + "\n" + QString::fromStdString(error), CClientUIInterface::MSG_ERROR);
279279
return;
280280
}

0 commit comments

Comments
 (0)