mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-07 23:03:04 +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.security.NoSuchAlgorithmException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
|
||||||
@ -75,6 +74,9 @@ public class Utils {
|
|||||||
*/
|
*/
|
||||||
public static BigInteger toNanoCoins(int coins, int cents) {
|
public static BigInteger toNanoCoins(int coins, int cents) {
|
||||||
checkArgument(cents < 100);
|
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);
|
BigInteger bi = BigInteger.valueOf(coins).multiply(COIN);
|
||||||
bi = bi.add(BigInteger.valueOf(cents).multiply(CENT));
|
bi = bi.add(BigInteger.valueOf(cents).multiply(CENT));
|
||||||
return bi;
|
return bi;
|
||||||
@ -106,10 +108,15 @@ public class Utils {
|
|||||||
* This takes string in a format understood by {@link BigDecimal#BigDecimal(String)},
|
* This takes string in a format understood by {@link BigDecimal#BigDecimal(String)},
|
||||||
* for example "0", "1", "0.10", "1.23E3", "1234.5E-5".
|
* 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) {
|
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) {
|
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 com.google.bitcoin.core.Utils.*;
|
||||||
import static junit.framework.Assert.assertEquals;
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
import static junit.framework.Assert.fail;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class UtilsTest {
|
public class UtilsTest {
|
||||||
@ -42,10 +43,18 @@ public class UtilsTest {
|
|||||||
// int version
|
// int version
|
||||||
assertEquals(CENT, toNanoCoins(0, 1));
|
assertEquals(CENT, toNanoCoins(0, 1));
|
||||||
|
|
||||||
// TODO: should this really pass?
|
try {
|
||||||
assertEquals(COIN.subtract(CENT), toNanoCoins(1, -1));
|
toNanoCoins(1, -1);
|
||||||
assertEquals(COIN.negate(), toNanoCoins(-1, 0));
|
fail();
|
||||||
assertEquals(COIN.negate(), toNanoCoins("-1"));
|
} catch (IllegalArgumentException e) {}
|
||||||
|
try {
|
||||||
|
toNanoCoins(-1, 0);
|
||||||
|
fail();
|
||||||
|
} catch (IllegalArgumentException e) {}
|
||||||
|
try {
|
||||||
|
toNanoCoins("-1");
|
||||||
|
fail();
|
||||||
|
} catch (ArithmeticException e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -71,7 +80,6 @@ public class UtilsTest {
|
|||||||
|
|
||||||
assertEquals("0.0015", bitcoinValueToPlainString(BigInteger.valueOf(150000)));
|
assertEquals("0.0015", bitcoinValueToPlainString(BigInteger.valueOf(150000)));
|
||||||
assertEquals("1.23", bitcoinValueToPlainString(toNanoCoins("1.23")));
|
assertEquals("1.23", bitcoinValueToPlainString(toNanoCoins("1.23")));
|
||||||
assertEquals("-1.23", bitcoinValueToPlainString(toNanoCoins("-1.23")));
|
|
||||||
|
|
||||||
assertEquals("0.1", bitcoinValueToPlainString(toNanoCoins("0.1")));
|
assertEquals("0.1", bitcoinValueToPlainString(toNanoCoins("0.1")));
|
||||||
assertEquals("1.1", bitcoinValueToPlainString(toNanoCoins("1.1")));
|
assertEquals("1.1", bitcoinValueToPlainString(toNanoCoins("1.1")));
|
||||||
@ -81,7 +89,10 @@ public class UtilsTest {
|
|||||||
assertEquals("54321.12345", bitcoinValueToPlainString(toNanoCoins("54321.12345")));
|
assertEquals("54321.12345", bitcoinValueToPlainString(toNanoCoins("54321.12345")));
|
||||||
assertEquals("654321.123456", bitcoinValueToPlainString(toNanoCoins("654321.123456")));
|
assertEquals("654321.123456", bitcoinValueToPlainString(toNanoCoins("654321.123456")));
|
||||||
assertEquals("7654321.1234567", bitcoinValueToPlainString(toNanoCoins("7654321.1234567")));
|
assertEquals("7654321.1234567", bitcoinValueToPlainString(toNanoCoins("7654321.1234567")));
|
||||||
|
try {
|
||||||
assertEquals("87654321.12345678", bitcoinValueToPlainString(toNanoCoins("87654321.12345678")));
|
assertEquals("87654321.12345678", bitcoinValueToPlainString(toNanoCoins("87654321.12345678")));
|
||||||
|
Assert.fail(); // More than MAX_MONEY
|
||||||
|
} catch (Exception e) {}
|
||||||
|
|
||||||
// check there are no trailing zeros
|
// check there are no trailing zeros
|
||||||
assertEquals("1", bitcoinValueToPlainString(toNanoCoins("1.0")));
|
assertEquals("1", bitcoinValueToPlainString(toNanoCoins("1.0")));
|
||||||
|
@ -44,14 +44,6 @@ public class BitcoinURITest {
|
|||||||
// example with spaces, ampersand and plus
|
// 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"));
|
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
|
// no amount, label present, message present
|
||||||
assertEquals("bitcoin:" + MAINNET_GOOD_ADDRESS + "?label=Hello&message=glory", BitcoinURI.convertToBitcoinURI(goodAddress, null, "Hello", "glory"));
|
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 {
|
public void testGood_Amount() throws BitcoinURIParseException {
|
||||||
// Test the decimal parsing
|
// Test the decimal parsing
|
||||||
testObject = new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":" + MAINNET_GOOD_ADDRESS
|
testObject = new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":" + MAINNET_GOOD_ADDRESS
|
||||||
+ "?amount=9876543210.12345678");
|
+ "?amount=6543210.12345678");
|
||||||
assertEquals("987654321012345678", testObject.getAmount().toString());
|
assertEquals("654321012345678", testObject.getAmount().toString());
|
||||||
|
|
||||||
// Test the decimal parsing
|
// Test the decimal parsing
|
||||||
testObject = new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":" + MAINNET_GOOD_ADDRESS
|
testObject = new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":" + MAINNET_GOOD_ADDRESS
|
||||||
@ -174,8 +166,8 @@ public class BitcoinURITest {
|
|||||||
|
|
||||||
// Test the integer parsing
|
// Test the integer parsing
|
||||||
testObject = new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":" + MAINNET_GOOD_ADDRESS
|
testObject = new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":" + MAINNET_GOOD_ADDRESS
|
||||||
+ "?amount=9876543210");
|
+ "?amount=6543210");
|
||||||
assertEquals("987654321000000000", testObject.getAmount().toString());
|
assertEquals("654321000000000", testObject.getAmount().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -246,9 +238,9 @@ public class BitcoinURITest {
|
|||||||
@Test
|
@Test
|
||||||
public void testGood_Combinations() throws BitcoinURIParseException {
|
public void testGood_Combinations() throws BitcoinURIParseException {
|
||||||
testObject = new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":" + MAINNET_GOOD_ADDRESS
|
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(
|
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());
|
testObject.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,4 +398,22 @@ public class BitcoinURITest {
|
|||||||
assertEquals("1KzTSfqjF2iKCduwz59nv2uqh1W2JsTxZH", uri.getAddress().toString());
|
assertEquals("1KzTSfqjF2iKCduwz59nv2uqh1W2JsTxZH", uri.getAddress().toString());
|
||||||
assertEquals(Utils.toNanoCoins(0, 1), uri.getAmount());
|
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…
x
Reference in New Issue
Block a user