Merge 553 via bugfix_qt_uri_amount_parser

This commit is contained in:
Luke Dashjr 2025-03-05 03:27:08 +00:00
commit 55e55d6819
3 changed files with 50 additions and 3 deletions

View File

@ -5,6 +5,7 @@ BIPs that are implemented by Bitcoin Core:
* [`BIP 13`](https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki): The address format for P2SH addresses has been implemented since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)).
* [`BIP 14`](https://github.com/bitcoin/bips/blob/master/bip-0014.mediawiki): The subversion string is being used as User Agent since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)).
* [`BIP 16`](https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki): The pay-to-script-hash evaluation rules have been implemented since **v0.6.0**, and took effect on *April 1st 2012* ([PR #748](https://github.com/bitcoin/bitcoin/pull/748)).
* [`BIP 20`](https://github.com/bitcoin/bips/blob/master/bip-0020.mediawiki): The extended amount format in URIs for Bitcoin payments has been implemented since **next-test 2011-12-23**
* [`BIP 21`](https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki): The URI format for Bitcoin payments has been implemented since **v0.6.0** ([PR #176](https://github.com/bitcoin/bitcoin/pull/176)).
* [`BIP 22`](https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki): The 'getblocktemplate' (GBT) RPC protocol for mining has been implemented since **v0.7.0** ([PR #936](https://github.com/bitcoin/bitcoin/pull/936)).
* [`BIP 23`](https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki): Some extensions to GBT have been implemented since **v0.10.0rc1**, including longpolling and block proposals ([PR #1816](https://github.com/bitcoin/bitcoin/pull/1816)).

View File

@ -156,6 +156,39 @@ void AddButtonShortcut(QAbstractButton* button, const QKeySequence& shortcut)
QObject::connect(new QShortcut(shortcut, button), &QShortcut::activated, [button]() { button->animateClick(); });
}
qint64 URIParseAmount(std::string amount_str, bool * const ok)
{
bool is_hex = false;
if (amount_str[0] == 'x' || amount_str[0] == 'X') {
is_hex = true;
amount_str = amount_str.substr(1);
}
size_t exponent_sep_pos = amount_str.find_first_of("Xx", 1);
int exponent;
if (exponent_sep_pos != std::string::npos) {
exponent = QString::fromStdString(amount_str.substr(exponent_sep_pos + 1)).toInt(ok, is_hex ? 0x10 : 10);
if (!*ok) return -1;
} else {
exponent = is_hex ? 4 : 8;
exponent_sep_pos = amount_str.size();
}
size_t fractional_sep_pos = amount_str.find('.');
size_t fractional_digits = 0;
if (fractional_sep_pos == std::string::npos)
fractional_sep_pos = exponent_sep_pos;
else
fractional_digits = (exponent_sep_pos - fractional_sep_pos) - 1;
exponent -= fractional_digits;
amount_str = amount_str.substr(0, fractional_sep_pos) + (fractional_digits ? amount_str.substr(fractional_sep_pos + 1, fractional_digits) : "");
if (exponent > 0) {
amount_str.append(exponent, '0');
} else if (exponent < 0) {
// Sub-satoshi amount? Truncate
amount_str = amount_str.substr(0, amount_str.size() + exponent);
}
return QString::fromStdString(amount_str).toLongLong(ok, is_hex ? 0x10 : 10);
}
bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out)
{
// return if URI is not valid or is no bitcoin: URI
@ -195,9 +228,9 @@ bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out)
{
if(!i->second.isEmpty())
{
if (!BitcoinUnits::parse(BitcoinUnit::BTC, i->second, &rv.amount)) {
return false;
}
bool ok;
rv.amount = URIParseAmount((i->second).toStdString(), &ok);
if (!ok) return false;
}
fShouldReturnFalse = false;
}

View File

@ -46,6 +46,16 @@ void URITests::uriTests()
QVERIFY(rv.amount == 10000000000LL);
QVERIFY(rv.label == QString("Wikipedia Example"));
uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=x100x4"));
QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv));
QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"));
QVERIFY(rv.amount == 16777216LL);
uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=100x2"));
QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv));
QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"));
QVERIFY(rv.amount == 10000LL);
uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?message=Wikipedia Example Address"));
QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv));
QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"));
@ -62,6 +72,9 @@ void URITests::uriTests()
uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=1,000&label=Wikipedia Example"));
QVERIFY(!GUIUtil::parseBitcoinURI(uri, &rv));
uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=x1,0000&label=Wikipedia Example"));
QVERIFY(!GUIUtil::parseBitcoinURI(uri, &rv));
uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=1,000.0&label=Wikipedia Example"));
QVERIFY(!GUIUtil::parseBitcoinURI(uri, &rv));