mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 09:57:02 +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:
parent
45ad946697
commit
a5b81d8562
@ -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) {
|
||||
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];
|
||||
if (!baseTypeDefinitions) {
|
||||
throw new Error(`Invalid primary type definition`);
|
||||
@ -432,31 +458,11 @@ export const sanitizeMessage = (msg, baseType, types) => {
|
||||
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(
|
||||
msg[msgKey],
|
||||
definedType.type,
|
||||
types,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// check if it's a valid solidity type
|
||||
const isSolidityType = solidityTypes().includes(nestedType);
|
||||
if (isSolidityType) {
|
||||
sanitizedMessage[msgKey] = msg[msgKey];
|
||||
}
|
||||
}
|
||||
});
|
||||
return sanitizedMessage;
|
||||
};
|
||||
|
@ -365,6 +365,10 @@ describe('util', () => {
|
||||
],
|
||||
},
|
||||
],
|
||||
nestArray: [
|
||||
[12, 34, 56],
|
||||
[56, 78, 89],
|
||||
],
|
||||
};
|
||||
primaryType = 'Mail';
|
||||
types = {
|
||||
@ -378,6 +382,8 @@ describe('util', () => {
|
||||
{ name: 'from', type: 'Person' },
|
||||
{ name: 'to', type: 'Person[]' },
|
||||
{ name: 'contents', type: 'string' },
|
||||
{ name: 'nestArray', type: 'uint256[2][2]' },
|
||||
{ name: 'nestedPeople', type: 'Person[][]' },
|
||||
],
|
||||
Person: [
|
||||
{ name: 'name', type: 'string' },
|
||||
@ -408,6 +414,67 @@ describe('util', () => {
|
||||
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', () => {
|
||||
message.do_not_display = 'one';
|
||||
message.do_not_display_2 = {
|
||||
|
Loading…
Reference in New Issue
Block a user