Skip to content

Commit

Permalink
Bring back custom validation
Browse files Browse the repository at this point in the history
  • Loading branch information
mattverse committed Mar 4, 2024
1 parent 63f4172 commit 33a4a85
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 5 deletions.
37 changes: 32 additions & 5 deletions types/coin.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"fmt"
"regexp"
"sort"
"strings"

Expand Down Expand Up @@ -841,14 +842,40 @@ func (coins Coins) Sort() Coins {
return coins
}

var (
reDecAmt = `[[:digit:]]+(?:\.[[:digit:]]+)?|\.[[:digit:]]+`
reSpc = `[[:space:]]*`

coinDenomRegex func() string

reDnm *regexp.Regexp
reDecCoin *regexp.Regexp
)

// SetCoinDenomRegex allows for coin's custom validation by overriding the regular
// expression string used for denom validation.
func SetCoinDenomRegex(reFn func() string) {
coinDenomRegex = reFn

reDnm = regexp.MustCompile(fmt.Sprintf(`^%s$`, coinDenomRegex()))
reDecCoin = regexp.MustCompile(fmt.Sprintf(`^(%s)%s(%s)$`, reDecAmt, reSpc, coinDenomRegex()))
}

// ValidateDenom is the default validation function for Coin.Denom.
func ValidateDenom(denom string) error {
// Convert the string to a byte slice as required by the Ragel-generated function.
denomBytes := []byte(denom)
if reDnm == nil || reDecCoin == nil {
// Convert the string to a byte slice as required by the Ragel-generated function.
denomBytes := []byte(denom)

// Call the Ragel-generated function.
if !MatchDenom(denomBytes) {
return fmt.Errorf("invalid denom: %s", denom)
// Call the Ragel-generated function.
if !MatchDenom(denomBytes) {
return fmt.Errorf("invalid denom: %s", denom)
}
} else {
// If reDnm has been initialized, use it for matching.
if !reDnm.MatchString(denom) {
return fmt.Errorf("invalid denom: %s", denom)
}
}

return nil
Expand Down
25 changes: 25 additions & 0 deletions types/coin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,31 @@ func (s *coinTestSuite) TestCoinIsValid() {
}
}

func (s *coinTestSuite) TestCustomValidation() {
newDnmRegex := `[\x{1F600}-\x{1F6FF}]`
reDnmString := `[a-zA-Z][a-zA-Z0-9/:._-]{2,127}`

sdk.SetCoinDenomRegex(func() string {
return newDnmRegex
})

cases := []struct {
coin sdk.Coin
expectPass bool
}{
{sdk.Coin{"🙂", math.NewInt(1)}, true},
{sdk.Coin{"🙁", math.NewInt(1)}, true},
{sdk.Coin{"🌶", math.NewInt(1)}, false}, // outside the unicode range listed above
{sdk.Coin{"asdf", math.NewInt(1)}, false},
{sdk.Coin{"", math.NewInt(1)}, false},
}

for i, tc := range cases {
s.Require().Equal(tc.expectPass, tc.coin.IsValid(), "unexpected result for IsValid, tc #%d", i)
}
sdk.SetCoinDenomRegex(func() string { return reDnmString })
}

func (s *coinTestSuite) TestCoinsDenoms() {
cases := []struct {
coins sdk.Coins
Expand Down

0 comments on commit 33a4a85

Please sign in to comment.