mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-01-31 15:22:16 +00:00
Eliminate support for parsing negative or too large amounts in Utils.toNanoCoins. Add tests for out of range URI amounts. Resolves issue 407.
This commit is contained in:
parent
d3eab06dba
commit
719a786db1
@ -29,7 +29,6 @@ import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
@ -75,6 +74,9 @@ public class Utils {
|
||||
*/
|
||||
public static BigInteger toNanoCoins(int coins, int cents) {
|
||||
checkArgument(cents < 100);
|
||||
checkArgument(cents >= 0);
|
||||
checkArgument(coins >= 0);
|
||||
checkArgument(coins < NetworkParameters.MAX_MONEY.divide(Utils.COIN).longValue());
|
||||
BigInteger bi = BigInteger.valueOf(coins).multiply(COIN);
|
||||
bi = bi.add(BigInteger.valueOf(cents).multiply(CENT));
|
||||
return bi;
|
||||
@ -106,10 +108,15 @@ public class Utils {
|
||||
* This takes string in a format understood by {@link BigDecimal#BigDecimal(String)},
|
||||
* for example "0", "1", "0.10", "1.23E3", "1234.5E-5".
|
||||
*
|
||||
* @throws ArithmeticException if you try to specify fractional nanocoins
|
||||
* @throws ArithmeticException if you try to specify fractional nanocoins, or nanocoins out of range.
|
||||
*/
|
||||
public static BigInteger toNanoCoins(String coins) {
|
||||
return new BigDecimal(coins).movePointRight(8).toBigIntegerExact();
|
||||
BigInteger bigint = new BigDecimal(coins).movePointRight(8).toBigIntegerExact();
|
||||
if (bigint.compareTo(BigInteger.ZERO) < 0)
|
||||
throw new ArithmeticException("Negative coins specified");
|
||||
if (bigint.compareTo(NetworkParameters.MAX_MONEY) > 0)
|
||||
throw new ArithmeticException("Amount larger than the total quantity of Bitcoins possible specified.");
|
||||
return bigint;
|
||||
}
|
||||
|
||||
public static void uint32ToByteArrayBE(long val, byte[] out, int offset) {
|
||||
|
@ -23,6 +23,7 @@ import java.math.BigInteger;
|
||||
|
||||
import static com.google.bitcoin.core.Utils.*;
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.fail;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class UtilsTest {
|
||||
@ -42,10 +43,18 @@ public class UtilsTest {
|
||||
// int version
|
||||
assertEquals(CENT, toNanoCoins(0, 1));
|
||||
|
||||
// TODO: should this really pass?
|
||||
assertEquals(COIN.subtract(CENT), toNanoCoins(1, -1));
|
||||
assertEquals(COIN.negate(), toNanoCoins(-1, 0));
|
||||
assertEquals(COIN.negate(), toNanoCoins("-1"));
|
||||
try {
|
||||
toNanoCoins(1, -1);
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {}
|
||||
try {
|
||||
toNanoCoins(-1, 0);
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {}
|
||||
try {
|
||||
toNanoCoins("-1");
|
||||
fail();
|
||||
} catch (ArithmeticException e) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -71,8 +80,7 @@ public class UtilsTest {
|
||||
|
||||
assertEquals("0.0015", bitcoinValueToPlainString(BigInteger.valueOf(150000)));
|
||||
assertEquals("1.23", bitcoinValueToPlainString(toNanoCoins("1.23")));
|
||||
assertEquals("-1.23", bitcoinValueToPlainString(toNanoCoins("-1.23")));
|
||||
|
||||
|
||||
assertEquals("0.1", bitcoinValueToPlainString(toNanoCoins("0.1")));
|
||||
assertEquals("1.1", bitcoinValueToPlainString(toNanoCoins("1.1")));
|
||||
assertEquals("21.12", bitcoinValueToPlainString(toNanoCoins("21.12")));
|
||||
@ -81,7 +89,10 @@ public class UtilsTest {
|
||||
assertEquals("54321.12345", bitcoinValueToPlainString(toNanoCoins("54321.12345")));
|
||||
assertEquals("654321.123456", bitcoinValueToPlainString(toNanoCoins("654321.123456")));
|
||||
assertEquals("7654321.1234567", bitcoinValueToPlainString(toNanoCoins("7654321.1234567")));
|
||||
assertEquals("87654321.12345678", bitcoinValueToPlainString(toNanoCoins("87654321.12345678")));
|
||||
try {
|
||||
assertEquals("87654321.12345678", bitcoinValueToPlainString(toNanoCoins("87654321.12345678")));
|
||||
Assert.fail(); // More than MAX_MONEY
|
||||
} catch (Exception e) {}
|
||||
|
||||
// check there are no trailing zeros
|
||||
assertEquals("1", bitcoinValueToPlainString(toNanoCoins("1.0")));
|
||||
|
@ -44,14 +44,6 @@ public class BitcoinURITest {
|
||||
// example with spaces, ampersand and plus
|
||||
assertEquals("bitcoin:" + MAINNET_GOOD_ADDRESS + "?amount=12.34&label=Hello%20World&message=Mess%20%26%20age%20%2B%20hope", BitcoinURI.convertToBitcoinURI(goodAddress, Utils.toNanoCoins("12.34"), "Hello World", "Mess & age + hope"));
|
||||
|
||||
// amount negative
|
||||
try {
|
||||
BitcoinURI.convertToBitcoinURI(goodAddress, Utils.toNanoCoins("-0.1"), "hope", "glory");
|
||||
fail("Expecting IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertTrue(e.getMessage().contains("Amount must be positive"));
|
||||
}
|
||||
|
||||
// no amount, label present, message present
|
||||
assertEquals("bitcoin:" + MAINNET_GOOD_ADDRESS + "?label=Hello&message=glory", BitcoinURI.convertToBitcoinURI(goodAddress, null, "Hello", "glory"));
|
||||
|
||||
@ -164,8 +156,8 @@ public class BitcoinURITest {
|
||||
public void testGood_Amount() throws BitcoinURIParseException {
|
||||
// Test the decimal parsing
|
||||
testObject = new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":" + MAINNET_GOOD_ADDRESS
|
||||
+ "?amount=9876543210.12345678");
|
||||
assertEquals("987654321012345678", testObject.getAmount().toString());
|
||||
+ "?amount=6543210.12345678");
|
||||
assertEquals("654321012345678", testObject.getAmount().toString());
|
||||
|
||||
// Test the decimal parsing
|
||||
testObject = new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":" + MAINNET_GOOD_ADDRESS
|
||||
@ -174,8 +166,8 @@ public class BitcoinURITest {
|
||||
|
||||
// Test the integer parsing
|
||||
testObject = new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":" + MAINNET_GOOD_ADDRESS
|
||||
+ "?amount=9876543210");
|
||||
assertEquals("987654321000000000", testObject.getAmount().toString());
|
||||
+ "?amount=6543210");
|
||||
assertEquals("654321000000000", testObject.getAmount().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -246,9 +238,9 @@ public class BitcoinURITest {
|
||||
@Test
|
||||
public void testGood_Combinations() throws BitcoinURIParseException {
|
||||
testObject = new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":" + MAINNET_GOOD_ADDRESS
|
||||
+ "?amount=9876543210&label=Hello%20World&message=Be%20well");
|
||||
+ "?amount=6543210&label=Hello%20World&message=Be%20well");
|
||||
assertEquals(
|
||||
"BitcoinURI['address'='1KzTSfqjF2iKCduwz59nv2uqh1W2JsTxZH','amount'='987654321000000000','label'='Hello World','message'='Be well']",
|
||||
"BitcoinURI['address'='1KzTSfqjF2iKCduwz59nv2uqh1W2JsTxZH','amount'='654321000000000','label'='Hello World','message'='Be well']",
|
||||
testObject.toString());
|
||||
}
|
||||
|
||||
@ -406,4 +398,22 @@ public class BitcoinURITest {
|
||||
assertEquals("1KzTSfqjF2iKCduwz59nv2uqh1W2JsTxZH", uri.getAddress().toString());
|
||||
assertEquals(Utils.toNanoCoins(0, 1), uri.getAmount());
|
||||
}
|
||||
|
||||
@Test(expected = BitcoinURIParseException.class)
|
||||
public void testBad_AmountTooPrecise() throws BitcoinURIParseException {
|
||||
new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":" + MAINNET_GOOD_ADDRESS
|
||||
+ "?amount=0.123456789");
|
||||
}
|
||||
|
||||
@Test(expected = BitcoinURIParseException.class)
|
||||
public void testBad_NegativeAmount() throws BitcoinURIParseException {
|
||||
new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":" + MAINNET_GOOD_ADDRESS
|
||||
+ "?amount=-1");
|
||||
}
|
||||
|
||||
@Test(expected = BitcoinURIParseException.class)
|
||||
public void testBad_TooLargeAmount() throws BitcoinURIParseException {
|
||||
new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":" + MAINNET_GOOD_ADDRESS
|
||||
+ "?amount=100000000");
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user