Skip to content

Commit 4f4a25d

Browse files
authored
signer/core: don't require capital lettered reference types (#26462)
1 parent 50e6539 commit 4f4a25d

File tree

2 files changed

+160
-21
lines changed

2 files changed

+160
-21
lines changed

signer/core/apitypes/types.go

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ import (
2727
"sort"
2828
"strconv"
2929
"strings"
30-
"unicode"
31-
"unicode/utf8"
3230

3331
"github.com/ethereum/go-ethereum/accounts"
3432
"github.com/ethereum/go-ethereum/common"
@@ -38,7 +36,7 @@ import (
3836
"github.com/ethereum/go-ethereum/crypto"
3937
)
4038

41-
var typedDataReferenceTypeRegexp = regexp.MustCompile(`^[A-Z](\w*)(\[\])?$`)
39+
var typedDataReferenceTypeRegexp = regexp.MustCompile(`^[A-Za-z](\w*)(\[\])?$`)
4240

4341
type ValidationInfo struct {
4442
Typ string `json:"type"`
@@ -224,15 +222,6 @@ func (t *Type) typeName() string {
224222
return t.Type
225223
}
226224

227-
func (t *Type) isReferenceType() bool {
228-
if len(t.Type) == 0 {
229-
return false
230-
}
231-
// Reference types must have a leading uppercase character
232-
r, _ := utf8.DecodeRuneInString(t.Type)
233-
return unicode.IsUpper(r)
234-
}
235-
236225
type Types map[string][]Type
237226

238227
type TypePriority struct {
@@ -731,15 +720,15 @@ func (t Types) validate() error {
731720
if typeKey == typeObj.Type {
732721
return fmt.Errorf("type %q cannot reference itself", typeObj.Type)
733722
}
734-
if typeObj.isReferenceType() {
735-
if _, exist := t[typeObj.typeName()]; !exist {
736-
return fmt.Errorf("reference type %q is undefined", typeObj.Type)
737-
}
738-
if !typedDataReferenceTypeRegexp.MatchString(typeObj.Type) {
739-
return fmt.Errorf("unknown reference type %q", typeObj.Type)
740-
}
741-
} else if !isPrimitiveTypeValid(typeObj.Type) {
742-
return fmt.Errorf("unknown type %q", typeObj.Type)
723+
if isPrimitiveTypeValid(typeObj.Type) {
724+
continue
725+
}
726+
// Must be reference type
727+
if _, exist := t[typeObj.typeName()]; !exist {
728+
return fmt.Errorf("reference type %q is undefined", typeObj.Type)
729+
}
730+
if !typedDataReferenceTypeRegexp.MatchString(typeObj.Type) {
731+
return fmt.Errorf("unknown reference type %q", typeObj.Type)
743732
}
744733
}
745734
}

signer/core/signed_data_test.go

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -848,3 +848,153 @@ func TestGnosisSafe(t *testing.T) {
848848
t.Fatal("expected equality")
849849
}
850850
}
851+
852+
var complexTypedDataLCRefType = `
853+
{
854+
"types": {
855+
"EIP712Domain": [
856+
{
857+
"name": "chainId",
858+
"type": "uint256"
859+
},
860+
{
861+
"name": "name",
862+
"type": "string"
863+
},
864+
{
865+
"name": "verifyingContract",
866+
"type": "address"
867+
},
868+
{
869+
"name": "version",
870+
"type": "string"
871+
}
872+
],
873+
"Action": [
874+
{
875+
"name": "action",
876+
"type": "string"
877+
},
878+
{
879+
"name": "params",
880+
"type": "string"
881+
}
882+
],
883+
"cCell": [
884+
{
885+
"name": "capacity",
886+
"type": "string"
887+
},
888+
{
889+
"name": "lock",
890+
"type": "string"
891+
},
892+
{
893+
"name": "type",
894+
"type": "string"
895+
},
896+
{
897+
"name": "data",
898+
"type": "string"
899+
},
900+
{
901+
"name": "extraData",
902+
"type": "string"
903+
}
904+
],
905+
"Transaction": [
906+
{
907+
"name": "DAS_MESSAGE",
908+
"type": "string"
909+
},
910+
{
911+
"name": "inputsCapacity",
912+
"type": "string"
913+
},
914+
{
915+
"name": "outputsCapacity",
916+
"type": "string"
917+
},
918+
{
919+
"name": "fee",
920+
"type": "string"
921+
},
922+
{
923+
"name": "action",
924+
"type": "Action"
925+
},
926+
{
927+
"name": "inputs",
928+
"type": "cCell[]"
929+
},
930+
{
931+
"name": "outputs",
932+
"type": "cCell[]"
933+
},
934+
{
935+
"name": "digest",
936+
"type": "bytes32"
937+
}
938+
]
939+
},
940+
"primaryType": "Transaction",
941+
"domain": {
942+
"chainId": "56",
943+
"name": "da.systems",
944+
"verifyingContract": "0x0000000000000000000000000000000020210722",
945+
"version": "1"
946+
},
947+
"message": {
948+
"DAS_MESSAGE": "SELL mobcion.bit FOR 100000 CKB",
949+
"inputsCapacity": "1216.9999 CKB",
950+
"outputsCapacity": "1216.9998 CKB",
951+
"fee": "0.0001 CKB",
952+
"digest": "0x53a6c0f19ec281604607f5d6817e442082ad1882bef0df64d84d3810dae561eb",
953+
"action": {
954+
"action": "start_account_sale",
955+
"params": "0x00"
956+
},
957+
"inputs": [
958+
{
959+
"capacity": "218 CKB",
960+
"lock": "das-lock,0x01,0x051c152f77f8efa9c7c6d181cc97ee67c165c506...",
961+
"type": "account-cell-type,0x01,0x",
962+
"data": "{ account: mobcion.bit, expired_at: 1670913958 }",
963+
"extraData": "{ status: 0, records_hash: 0x55478d76900611eb079b22088081124ed6c8bae21a05dd1a0d197efcc7c114ce }"
964+
}
965+
],
966+
"outputs": [
967+
{
968+
"capacity": "218 CKB",
969+
"lock": "das-lock,0x01,0x051c152f77f8efa9c7c6d181cc97ee67c165c506...",
970+
"type": "account-cell-type,0x01,0x",
971+
"data": "{ account: mobcion.bit, expired_at: 1670913958 }",
972+
"extraData": "{ status: 1, records_hash: 0x55478d76900611eb079b22088081124ed6c8bae21a05dd1a0d197efcc7c114ce }"
973+
},
974+
{
975+
"capacity": "201 CKB",
976+
"lock": "das-lock,0x01,0x051c152f77f8efa9c7c6d181cc97ee67c165c506...",
977+
"type": "account-sale-cell-type,0x01,0x",
978+
"data": "0x1209460ef3cb5f1c68ed2c43a3e020eec2d9de6e...",
979+
"extraData": ""
980+
}
981+
]
982+
}
983+
}
984+
`
985+
986+
func TestComplexTypedDataWithLowercaseReftype(t *testing.T) {
987+
var td apitypes.TypedData
988+
err := json.Unmarshal([]byte(complexTypedDataLCRefType), &td)
989+
if err != nil {
990+
t.Fatalf("unmarshalling failed '%v'", err)
991+
}
992+
_, sighash, err := sign(td)
993+
if err != nil {
994+
t.Fatal(err)
995+
}
996+
expSigHash := common.FromHex("0x49191f910874f0148597204d9076af128d4694a7c4b714f1ccff330b87207bff")
997+
if !bytes.Equal(expSigHash, sighash) {
998+
t.Fatalf("Error, got %x, wanted %x", sighash, expSigHash)
999+
}
1000+
}

0 commit comments

Comments
 (0)