diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index b72f1282..3fad4d92 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -723,7 +723,7 @@ void BitcoinGUI::dropEvent(QDropEvent *event) QList urls = event->mimeData()->urls(); foreach(const QUrl &url, urls) { - sendCoinsPage->handleURL(&url); + sendCoinsPage->handleURL(url.toString()); } } @@ -733,8 +733,7 @@ void BitcoinGUI::dropEvent(QDropEvent *event) void BitcoinGUI::handleURL(QString strURL) { gotoSendCoinsPage(); - QUrl url = QUrl(strURL); - sendCoinsPage->handleURL(&url); + sendCoinsPage->handleURL(strURL); } void BitcoinGUI::setEncryptionStatus(int status) diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 29ef554a..02fc3b67 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -49,15 +49,15 @@ void GUIUtil::setupAmountWidget(QLineEdit *widget, QWidget *parent) widget->setAlignment(Qt::AlignRight|Qt::AlignVCenter); } -bool GUIUtil::parseBitcoinURL(const QUrl *url, SendCoinsRecipient *out) +bool GUIUtil::parseBitcoinURL(const QUrl &url, SendCoinsRecipient *out) { - if(url->scheme() != QString("bitcoin")) + if(url.scheme() != QString("bitcoin")) return false; SendCoinsRecipient rv; - rv.address = url->path(); + rv.address = url.path(); rv.amount = 0; - QList > items = url->queryItems(); + QList > items = url.queryItems(); for (QList >::iterator i = items.begin(); i != items.end(); i++) { bool fShouldReturnFalse = false; @@ -94,6 +94,20 @@ bool GUIUtil::parseBitcoinURL(const QUrl *url, SendCoinsRecipient *out) return true; } +bool GUIUtil::parseBitcoinURL(QString url, SendCoinsRecipient *out) +{ + // Convert bitcoin:// to bitcoin: + // + // Cannot handle this later, because bitcoin:// will cause Qt to see the part after // as host, + // which will lowercase it (and thus invalidate the address). + if(url.startsWith("bitcoin://")) + { + url.replace(0, 10, "bitcoin:"); + } + QUrl urlInstance(url); + return parseBitcoinURL(urlInstance, out); +} + QString GUIUtil::HtmlEscape(const QString& str, bool fMultiLine) { QString escaped = Qt::escape(str); diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 3a81bd2f..0c8b1718 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -31,7 +31,8 @@ public: // Parse "bitcoin:" URL into recipient object, return true on succesful parsing // See Bitcoin URL definition discussion here: https://bitcointalk.org/index.php?topic=33490.0 - static bool parseBitcoinURL(const QUrl *url, SendCoinsRecipient *out); + static bool parseBitcoinURL(const QUrl &url, SendCoinsRecipient *out); + static bool parseBitcoinURL(QString url, SendCoinsRecipient *out); // HTML escaping for rich text controls static QString HtmlEscape(const QString& str, bool fMultiLine=false); diff --git a/src/qt/qtipcserver.cpp b/src/qt/qtipcserver.cpp index 90d5c142..018461a9 100644 --- a/src/qt/qtipcserver.cpp +++ b/src/qt/qtipcserver.cpp @@ -30,16 +30,7 @@ void ipcThread(void* parg) ptime d = boost::posix_time::microsec_clock::universal_time() + millisec(100); if(mq->timed_receive(&strBuf, sizeof(strBuf), nSize, nPriority, d)) { - strBuf[nSize] = '\0'; - // Convert bitcoin:// URLs to bitcoin: URIs - if (strBuf[8] == '/' && strBuf[9] == '/') - { - for (int i = 8; i < 256; i++) - { - strBuf[i] = strBuf[i+2]; - } - } - ThreadSafeHandleURL(strBuf); + ThreadSafeHandleURL(std::string(strBuf, nSize)); Sleep(1000); } if (fShutdown) @@ -66,16 +57,7 @@ void ipcInit() ptime d = boost::posix_time::microsec_clock::universal_time() + millisec(1); if(mq->timed_receive(&strBuf, sizeof(strBuf), nSize, nPriority, d)) { - strBuf[nSize] = '\0'; - // Convert bitcoin:// URLs to bitcoin: URIs - if (strBuf[8] == '/' && strBuf[9] == '/') - { - for (int i = 8; i < 256; i++) - { - strBuf[i] = strBuf[i+2]; - } - } - ThreadSafeHandleURL(strBuf); + ThreadSafeHandleURL(std::string(strBuf, nSize)); } else break; diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 0d9a604d..964313ea 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -265,7 +265,7 @@ void SendCoinsDialog::pasteEntry(const SendCoinsRecipient &rv) } -void SendCoinsDialog::handleURL(const QUrl *url) +void SendCoinsDialog::handleURL(const QString &url) { SendCoinsRecipient rv; if(!GUIUtil::parseBitcoinURL(url, &rv)) diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index 847ee8b6..4dc3f08b 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -30,7 +30,7 @@ public: QWidget *setupTabChain(QWidget *prev); void pasteEntry(const SendCoinsRecipient &rv); - void handleURL(const QUrl *url); + void handleURL(const QString &url); public slots: void clear(); diff --git a/src/qt/test/urltests.cpp b/src/qt/test/urltests.cpp index 5ecc8462..1f11795a 100644 --- a/src/qt/test/urltests.cpp +++ b/src/qt/test/urltests.cpp @@ -18,51 +18,54 @@ void URLTests::urlTests() SendCoinsRecipient rv; QUrl url; url.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?req-dontexist=")); - QVERIFY(!GUIUtil::parseBitcoinURL(&url, &rv)); + QVERIFY(!GUIUtil::parseBitcoinURL(url, &rv)); url.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?dontexist=")); - QVERIFY(GUIUtil::parseBitcoinURL(&url, &rv)); + QVERIFY(GUIUtil::parseBitcoinURL(url, &rv)); QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); QVERIFY(rv.label == QString()); QVERIFY(rv.amount == 0); url.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?label=Wikipedia Example Address")); - QVERIFY(GUIUtil::parseBitcoinURL(&url, &rv)); + QVERIFY(GUIUtil::parseBitcoinURL(url, &rv)); QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); QVERIFY(rv.label == QString("Wikipedia Example Address")); QVERIFY(rv.amount == 0); url.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=0.001")); - QVERIFY(GUIUtil::parseBitcoinURL(&url, &rv)); + QVERIFY(GUIUtil::parseBitcoinURL(url, &rv)); QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); QVERIFY(rv.label == QString()); QVERIFY(rv.amount == 100000); url.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=1.001")); - QVERIFY(GUIUtil::parseBitcoinURL(&url, &rv)); + QVERIFY(GUIUtil::parseBitcoinURL(url, &rv)); QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); QVERIFY(rv.label == QString()); QVERIFY(rv.amount == 100100000); url.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=100&label=Wikipedia Example")); - QVERIFY(GUIUtil::parseBitcoinURL(&url, &rv)); + QVERIFY(GUIUtil::parseBitcoinURL(url, &rv)); QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); QVERIFY(rv.amount == 10000000000); QVERIFY(rv.label == QString("Wikipedia Example")); url.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?message=Wikipedia Example Address")); - QVERIFY(GUIUtil::parseBitcoinURL(&url, &rv)); + QVERIFY(GUIUtil::parseBitcoinURL(url, &rv)); QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); QVERIFY(rv.label == QString()); + + QVERIFY(GUIUtil::parseBitcoinURL("bitcoin://175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?message=Wikipedia Example Address", &rv)); + QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); QVERIFY(rv.label == QString()); // We currently dont implement the message paramenter (ok, yea, we break spec...) url.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?req-message=Wikipedia Example Address")); - QVERIFY(!GUIUtil::parseBitcoinURL(&url, &rv)); + QVERIFY(!GUIUtil::parseBitcoinURL(url, &rv)); url.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=1,000&label=Wikipedia Example")); - QVERIFY(!GUIUtil::parseBitcoinURL(&url, &rv)); + QVERIFY(!GUIUtil::parseBitcoinURL(url, &rv)); url.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=1,000.0&label=Wikipedia Example")); - QVERIFY(!GUIUtil::parseBitcoinURL(&url, &rv)); + QVERIFY(!GUIUtil::parseBitcoinURL(url, &rv)); }