Bitcoin amounts are stored as uint64 in the protobuf messages. Amounts over 0x7FFFFFFFFFFFFFFF will be considered negative when this line is executed: QList<std::pair<CScript, CAmount> > sendingTos = request.getPayTo(); (in PaymentServer::processPaymentRequest() in qt\paymentserver.cpp)
Negative values should be discarded by the dust check : if (txOut.IsDust(::minRelayTxFee)) Nevertheless recipient.amount will still accumulate all positive values and may overflow, since the payment protocol allows the merchant to specify many output addresses and each one has a separate amount. So it is still possible to create a small positive total amount by overflowing the int64 range with several large positive amounts. For example: max_uint64 /3 + max_uint64 /3 + max_uint64 /3 +2 == 1 The user will be presented with a dialog asking to pay a total of 1 BTC, but internally the operation will fail, because the independent constituent payment amounts will not be able to be fulfilled.
This has the nasty effect that the user may think he may have been robbed, because even if the user has 100 BTC, the software will tell the user "The amount exceeds your balance." when paying to an overflowed 1 BTC.
There may be other possibilities, since there are several places where conversions between uint64 and int64 take place.
Suggested correction:
bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoinsRecipient& recipient) { .... CTxOut txOut(sendingTo.second, sendingTo.first); // BEGIN ADD if (!MoneyRange(sendingTo.second)) { emit message(tr("Payment request rejected"), tr("Invalid money range."), CClientUIInterface::MSG_ERROR); return false; } // END ADD .... recipient.amount += sendingTo.second; ... // BEGIN ADD if (!MoneyRange(recipient.amount)) { emit message(tr("Payment request rejected"), tr("Invalid accumulated money range."), CClientUIInterface::MSG_ERROR); return false; } // END ADD