diff --git a/types/coin.go b/types/coin.go index 0499e58c0f..efc79b0b80 100644 --- a/types/coin.go +++ b/types/coin.go @@ -24,18 +24,18 @@ var reDenom = regexp.MustCompile("([^\\d\\W]+)") var reAmt = regexp.MustCompile("(\\d+)") func ParseCoin(str string) (Coin, error) { - var coin Coin - if len(str) > 0 { - amt, err := strconv.Atoi(reAmt.FindString(str)) - if err != nil { - return coin, err - } - denom := reDenom.FindString(str) - coin = Coin{denom, int64(amt)} + if len(str) == 0 { + return coin, errors.New("Empty string is invalid coin") } + amt, err := strconv.Atoi(reAmt.FindString(str)) + if err != nil { + return coin, err + } + denom := reDenom.FindString(str) + coin = Coin{denom, int64(amt)} return coin, nil } @@ -56,17 +56,20 @@ func (coins Coins) String() string { } func ParseCoins(str string) (Coins, error) { + // empty string is empty list... + if len(str) == 0 { + return nil, nil + } + split := strings.Split(str, ",") var coins Coins for _, el := range split { - if len(el) > 0 { - coin, err := ParseCoin(el) - if err != nil { - return coins, err - } - coins = append(coins, coin) + coin, err := ParseCoin(el) + if err != nil { + return coins, err } + coins = append(coins, coin) } // ensure they are in proper order, to avoid random failures later diff --git a/types/coin_test.go b/types/coin_test.go index bf99d0caab..39149d7e8d 100644 --- a/types/coin_test.go +++ b/types/coin_test.go @@ -68,6 +68,11 @@ func TestParse(t *testing.T) { {"99bar,1foo", true, Coins{{"bar", 99}, {"foo", 1}}}, {"98 bar , 1 foo ", true, Coins{{"bar", 98}, {"foo", 1}}}, {"2foo, 97 bar", true, Coins{{"bar", 97}, {"foo", 2}}}, + {"5 mycoin,", false, nil}, // no empty coins in a list + {"2 3foo, 97 bar", false, nil}, // 3foo is invalid coin name + {"11me coin, 12you coin", false, nil}, // no spaces in coin names + {"1.2btc", false, nil}, // amount must be integer + {"5foo-bar", false, nil}, // once more, only letters in coin name } for _, tc := range cases {