1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-22 18:00:18 +01:00

Fix message on sign typed data v4 screen (#16552)

Co-authored-by: Frederik Bolding <frederik.bolding@gmail.com>
This commit is contained in:
amerkadicE 2022-11-18 17:04:52 +01:00 committed by GitHub
parent 45ad946697
commit a5b81d8562
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 99 additions and 26 deletions

View File

@ -411,11 +411,37 @@ const solidityTypes = () => {
]; ];
}; };
export const sanitizeMessage = (msg, baseType, types) => { const SOLIDITY_TYPES = solidityTypes();
const stripArrayType = (potentialArrayType) =>
potentialArrayType.replace(/\[[[0-9]*\]*/gu, '');
const stripOneLayerofNesting = (potentialArrayType) =>
potentialArrayType.replace(/\[[[0-9]*\]/u, '');
const isArrayType = (potentialArrayType) =>
potentialArrayType.match(/\[[[0-9]*\]*/u) !== null;
const isSolidityType = (type) => SOLIDITY_TYPES.includes(type);
export const sanitizeMessage = (msg, primaryType, types) => {
if (!types) { if (!types) {
throw new Error(`Invalid types definition`); throw new Error(`Invalid types definition`);
} }
// Primary type can be an array.
const isArray = primaryType && isArrayType(primaryType);
if (isArray) {
return msg.map((value) =>
sanitizeMessage(value, stripOneLayerofNesting(primaryType), types),
);
} else if (isSolidityType(primaryType)) {
return msg;
}
// If not, assume to be struct
const baseType = isArray ? stripArrayType(primaryType) : primaryType;
const baseTypeDefinitions = types[baseType]; const baseTypeDefinitions = types[baseType];
if (!baseTypeDefinitions) { if (!baseTypeDefinitions) {
throw new Error(`Invalid primary type definition`); throw new Error(`Invalid primary type definition`);
@ -432,31 +458,11 @@ export const sanitizeMessage = (msg, baseType, types) => {
return; return;
} }
// key has a type. check if the definedType is also a type
const nestedType = definedType.type.replace(/\[\]$/u, '');
const nestedTypeDefinition = types[nestedType];
if (nestedTypeDefinition) {
if (definedType.type.endsWith('[]') > 0) {
// nested array
sanitizedMessage[msgKey] = msg[msgKey].map((value) =>
sanitizeMessage(value, nestedType, types),
);
} else {
// nested object
sanitizedMessage[msgKey] = sanitizeMessage( sanitizedMessage[msgKey] = sanitizeMessage(
msg[msgKey], msg[msgKey],
definedType.type, definedType.type,
types, types,
); );
}
} else {
// check if it's a valid solidity type
const isSolidityType = solidityTypes().includes(nestedType);
if (isSolidityType) {
sanitizedMessage[msgKey] = msg[msgKey];
}
}
}); });
return sanitizedMessage; return sanitizedMessage;
}; };

View File

@ -365,6 +365,10 @@ describe('util', () => {
], ],
}, },
], ],
nestArray: [
[12, 34, 56],
[56, 78, 89],
],
}; };
primaryType = 'Mail'; primaryType = 'Mail';
types = { types = {
@ -378,6 +382,8 @@ describe('util', () => {
{ name: 'from', type: 'Person' }, { name: 'from', type: 'Person' },
{ name: 'to', type: 'Person[]' }, { name: 'to', type: 'Person[]' },
{ name: 'contents', type: 'string' }, { name: 'contents', type: 'string' },
{ name: 'nestArray', type: 'uint256[2][2]' },
{ name: 'nestedPeople', type: 'Person[][]' },
], ],
Person: [ Person: [
{ name: 'name', type: 'string' }, { name: 'name', type: 'string' },
@ -408,6 +414,67 @@ describe('util', () => {
expect(result.to[0].wallets).toHaveLength(3); expect(result.to[0].wallets).toHaveLength(3);
}); });
it('should return parsed nested array if defined', () => {
const result = util.sanitizeMessage(
{
nestArray: [
[12, 34, 56],
[56, 78, 89],
],
},
primaryType,
types,
);
expect(result.nestArray).toHaveLength(2);
expect(result.nestArray[0]).toHaveLength(3);
expect(result.nestArray[0][0]).toStrictEqual(12);
expect(result.nestArray[0][2]).toStrictEqual(56);
});
it('should return parsed nested array with struct if defined', () => {
const msg = {
nestedPeople: [
[
{
name: 'Bob',
wallets: [
'0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
'0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57',
'0xB0B0b0b0b0b0B000000000000000000000000000',
],
},
],
[
{
name: 'Ben',
wallets: [
'0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
'0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57',
'0xB0B0b0b0b0b0B000000000000000000000000000',
],
},
{
name: 'Brandon',
wallets: [
'0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
'0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57',
'0xB0B0b0b0b0b0B000000000000000000000000000',
],
},
],
],
};
const result = util.sanitizeMessage(msg, primaryType, types);
expect(result.nestedPeople).toHaveLength(2);
expect(result.nestedPeople[0]).toHaveLength(1);
expect(result.nestedPeople[0][0].name).toStrictEqual('Bob');
expect(result.nestedPeople[0][0].wallets).toHaveLength(3);
expect(result.nestedPeople[0][0].wallets[0]).toStrictEqual(
'0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
);
expect(result.nestedPeople[1][1].name).toStrictEqual('Brandon');
});
it('should return ignore message data with unknown types', () => { it('should return ignore message data with unknown types', () => {
message.do_not_display = 'one'; message.do_not_display = 'one';
message.do_not_display_2 = { message.do_not_display_2 = {