Static Analysis: fixes suggested by axic

pull/7/head
soad003 7 years ago
parent fd1c024de6
commit 94783ee1a2
  1. 2
      remix-solidity/src/analysis/modules/similarVariableNames.js
  2. 47
      remix-solidity/src/analysis/modules/staticAnalysisCommon.js
  3. 28
      remix-solidity/test/analysis/staticAnalysisCommon-test.js

@ -69,7 +69,7 @@ function isCommonPrefixedVersion (varName1, varName2) {
}
function isCommonNrSuffixVersion (varName1, varName2) {
var ref = '^' + util.escapeRegExp(varName1.slice(0, -1)) + '[0-9]$'
var ref = '^' + util.escapeRegExp(varName1.slice(0, -1)) + '[0-9]*$'
return varName2.match(ref) != null
}

@ -27,7 +27,10 @@ var basicTypes = {
UINT: 'uint256',
BOOL: 'bool',
ADDRESS: 'address',
BYTES32: 'bytes32'
BYTES32: 'bytes32',
STRING_MEM: 'string memory',
BYTES_MEM: 'bytes memory',
BYTES4: 'bytes4'
}
var basicRegex = {
@ -57,10 +60,10 @@ var builtinFunctions = {
'mulmod(uint256,uint256,uint256)': true,
'selfdestruct(address)': true,
'revert()': true,
'revert(string memory)': true,
'assert(bool)': true,
'require(bool)': true,
'require(bool,string memory)': true,
'revert(string memory)': true,
'gasleft()': true,
'blockhash(uint)': true
}
@ -82,6 +85,29 @@ var specialVariables = {
}
}
var abiNamespace = {
ENCODE: {
obj: 'abi',
member: 'encode',
type: buildFunctionSignature([], [basicTypes.BYTES_MEM], false, 'pure')
},
ENCODEPACKED: {
obj: 'abi',
member: 'encodePacked',
type: buildFunctionSignature([], [basicTypes.BYTES_MEM], false, 'pure')
},
ENCODE_SELECT: {
obj: 'abi',
member: 'encodeWithSelector',
type: buildFunctionSignature([basicTypes.BYTES4], [basicTypes.BYTES_MEM], false, 'pure')
},
ENCODE_SIG: {
obj: 'abi',
member: 'encodeWithSignature',
type: buildFunctionSignature([basicTypes.STRING_MEM], [basicTypes.BYTES_MEM], false, 'pure')
}
}
// #################### Trivial Getters
function getType (node) {
@ -441,7 +467,16 @@ function isLocalCallGraphRelevantNode (node) {
* @return {bool}
*/
function isBuiltinFunctionCall (node) {
return isLocalCall(node) && builtinFunctions[getLocalCallName(node) + '(' + getFunctionCallTypeParameterType(node) + ')'] === true
return (isLocalCall(node) && builtinFunctions[getLocalCallName(node) + '(' + getFunctionCallTypeParameterType(node) + ')'] === true) || isAbiNamespaceCall(node)
}
/**
* True if is builtin function like assert, sha3, erecover, ...
* @node {ASTNode} some AstNode
* @return {bool}
*/
function isAbiNamespaceCall (node) {
return Object.keys(abiNamespace).some((key) => abiNamespace.hasOwnProperty(key) && node.children && node.children[0] && isSpecialVariableAccess(node.children[0], abiNamespace[key]))
}
/**
@ -809,8 +844,8 @@ function exactMatch (regexStr) {
* list of return type names
* @return {Boolean} isPayable
*/
function buildFunctionSignature (paramTypes, returnTypes, isPayable) {
return 'function (' + util.concatWithSeperator(paramTypes, ',') + ')' + ((isPayable) ? ' payable' : '') + ((returnTypes.length) ? ' returns (' + util.concatWithSeperator(returnTypes, ',') + ')' : '')
function buildFunctionSignature (paramTypes, returnTypes, isPayable, additionalMods) {
return 'function (' + util.concatWithSeperator(paramTypes, ',') + ')' + ((isPayable) ? ' payable' : '') + ((additionalMods) ? ' ' + additionalMods : '') + ((returnTypes.length) ? ' returns (' + util.concatWithSeperator(returnTypes, ',') + ')' : '')
}
/**
@ -859,6 +894,8 @@ module.exports = {
// #################### Complex Node Identification
isDeleteOfDynamicArray: isDeleteOfDynamicArray,
isAbiNamespaceCall: isAbiNamespaceCall,
isSpecialVariableAccess: isSpecialVariableAccess,
isDynamicArrayAccess: isDynamicArrayAccess,
hasFunctionBody: hasFunctionBody,
isInteraction: isInteraction,

@ -7,12 +7,20 @@ function escapeRegExp (str) {
}
test('staticAnalysisCommon.helpers.buildFunctionSignature', function (t) {
t.plan(7)
t.plan(9)
t.equal(common.helpers.buildFunctionSignature([common.basicTypes.UINT, common.basicTypes.ADDRESS], [common.basicTypes.BOOL], false),
'function (uint256,address) returns (bool)',
'two params and return value without payable')
t.equal(common.helpers.buildFunctionSignature([common.basicTypes.UINT, common.basicTypes.ADDRESS], [common.basicTypes.BOOL], false, 'pure'),
'function (uint256,address) pure returns (bool)',
'two params and return value without payable but pure')
t.equal(common.helpers.buildFunctionSignature([common.basicTypes.UINT, common.basicTypes.ADDRESS], [common.basicTypes.BOOL], true, 'pure'),
'function (uint256,address) payable pure returns (bool)',
'two params and return value without payable but pure')
t.equal(common.helpers.buildFunctionSignature([common.basicTypes.UINT, common.basicTypes.BYTES32, common.basicTypes.BYTES32], [], true),
'function (uint256,bytes32,bytes32) payable',
'three params and no return with payable')
@ -2110,3 +2118,21 @@ test('staticAnalysisCommon: isDeleteOfDynamicArray', function (t) {
t.equals(common.isDeleteOfDynamicArray(node), true)
t.equals(common.isDynamicArrayAccess(node.children[0]), true, 'Extracts right type')
})
test('staticAnalysisCommon: isAbiNamespaceCall', function (t) {
t.plan(8)
var node1 = {'attributes': {'argumentTypes': null, 'isConstant': false, 'isLValue': false, 'isPure': false, 'isStructConstructorCall': false, 'lValueRequested': false, 'names': [null], 'type': 'bytes memory', 'type_conversion': false}, 'children': [{'attributes': {'argumentTypes': [{'typeIdentifier': 't_uint256', 'typeString': 'uint256'}, {'typeIdentifier': 't_uint256', 'typeString': 'uint256'}], 'isConstant': false, 'isLValue': false, 'isPure': false, 'lValueRequested': false, 'member_name': 'encode', 'referencedDeclaration': null, 'type': 'function () pure returns (bytes memory)'}, 'children': [{'attributes': {'argumentTypes': null, 'overloadedDeclarations': [null], 'referencedDeclaration': 64, 'type': 'abi', 'value': 'abi'}, 'id': 26, 'name': 'Identifier', 'src': '245: 3:0'}], 'id': 28, 'name': 'MemberAccess', 'src': '245:10:0'}, {'attributes': {'argumentTypes': null, 'overloadedDeclarations': [null], 'referencedDeclaration': 7, 'type': 'uint256', 'value': 'a'}, 'id': 29, 'name': 'Identifier', 'src': '256:1:0'}, {'attributes': {'argumentTypes': null, 'overloadedDeclarations': [null], 'referencedDeclaration': 15, 'type': 'uint256', 'value': 'b'}, 'id': 30, 'name': 'Identifier', 'src': '258:1:0'}], 'id': 31, 'name': 'FunctionCall', 'src': '245:15:0'}
var node2 = {'attributes': {'argumentTypes': null, 'isConstant': false, 'isLValue': false, 'isPure': false, 'isStructConstructorCall': false, 'lValueRequested': false, 'names': [null], 'type': 'bytes memory', 'type_conversion': false}, 'children': [{'attributes': {'argumentTypes': [{'typeIdentifier': 't_uint256', 'typeString': 'uint256'}, {'typeIdentifier': 't_uint256', 'typeString': 'uint256'}], 'isConstant': false, 'isLValue': false, 'isPure': false, 'lValueRequested': false, 'member_name': 'encodePacked', 'referencedDeclaration': null, 'type': 'function () pure returns (bytes memory)'}, 'children': [{'attributes': {'argumentTypes': null, 'overloadedDeclarations': [null], 'referencedDeclaration': 64, 'type': 'abi', 'value': 'abi'}, 'id': 33, 'name': 'Identifier', 'src': '279:3:0'}], 'id': 35, 'name': 'MemberAccess', 'src': '279:16:0'}, {'attributes': {'argumentTypes': null, 'overloadedDeclarations': [null], 'referencedDeclaration': 7, 'type': 'uint256', 'value': 'a'}, 'id': 36, 'name': 'Identifier', 'src': '296:1:0'}, {'attributes': {'argumentTypes': null, 'overloadedDeclarations': [null], 'referencedDeclaration': 15, 'type': 'uint256', 'value': 'b'}, 'id': 37, 'name': 'Identifier', 'src': '298:1:0'}], 'id': 38, 'name': 'FunctionCall', 'src': '279:21:0'}
var node3 = {'attributes': {'argumentTypes': null, 'isConstant': false, 'isLValue': false, 'isPure': false, 'isStructConstructorCall': false, 'lValueRequested': false, 'names': [null], 'type': 'bytes memory', 'type_conversion': false}, 'children': [{'attributes': {'argumentTypes': [{'typeIdentifier': 't_bytes4', 'typeString': 'bytes4'}, {'typeIdentifier': 't_uint256', 'typeString': 'uint256'}, {'typeIdentifier': 't_uint256', 'typeString': 'uint256'}], 'isConstant': false, 'isLValue': false, 'isPure': false, 'lValueRequested': false, 'member_name': 'encodeWithSelector', 'referencedDeclaration': null, 'type': 'function (bytes4) pure returns (bytes memory)'}, 'children': [{'attributes': {'argumentTypes': null, 'overloadedDeclarations': [null], 'referencedDeclaration': 64, 'type': 'abi', 'value': 'abi'}, 'id': 40, 'name': 'Identifier', 'src': '319:3:0'}], 'id': 42, 'name': 'MemberAccess', 'src': '319:22:0'}, {'attributes': {'argumentTypes': null, 'overloadedDeclarations': [null], 'referencedDeclaration': 19, 'type': 'bytes4', 'value': 'selector'}, 'id': 43, 'name': 'Identifier', 'src': '342:8:0'}, {'attributes': {'argumentTypes': null, 'overloadedDeclarations': [null], 'referencedDeclaration': 7, 'type': 'uint256', 'value': 'a'}, 'id': 44, 'name': 'Identifier', 'src': '352:1:0'}, {'attributes': {'argumentTypes': null, 'overloadedDeclarations': [null], 'referencedDeclaration': 15, 'type': 'uint256', 'value': 'b'}, 'id': 45, 'name': 'Identifier', 'src': '355:1:0'}], 'id': 46, 'name': 'FunctionCall', 'src': '319:38:0'}
var node4 = {'attributes': {'argumentTypes': null, 'isConstant': false, 'isLValue': false, 'isPure': false, 'isStructConstructorCall': false, 'lValueRequested': false, 'names': [null], 'type': 'bytes memory', 'type_conversion': false}, 'children': [{'attributes': {'argumentTypes': [{'typeIdentifier': 't_string_memory_ptr', 'typeString': 'string memory'}, {'typeIdentifier': 't_uint256', 'typeString': 'uint256'}, {'typeIdentifier': 't_uint256', 'typeString': 'uint256'}], 'isConstant': false, 'isLValue': false, 'isPure': false, 'lValueRequested': false, 'member_name': 'encodeWithSignature', 'referencedDeclaration': null, 'type': 'function (string memory) pure returns (bytes memory)'}, 'children': [{'attributes': {'argumentTypes': null, 'overloadedDeclarations': [null], 'referencedDeclaration': 64, 'type': 'abi', 'value': 'abi'}, 'id': 48, 'name': 'Identifier', 'src': '367:3:0'}], 'id': 50, 'name': 'MemberAccess', 'src': '367:23:0'}, {'attributes': {'argumentTypes': null, 'overloadedDeclarations': [null], 'referencedDeclaration': 11, 'type': 'string memory', 'value': 'sig'}, 'id': 51, 'name': 'Identifier', 'src': '391:3:0'}, {'attributes': {'argumentTypes': null, 'overloadedDeclarations': [null], 'referencedDeclaration': 7, 'type': 'uint256', 'value': 'a'}, 'id': 52, 'name': 'Identifier', 'src': '396:1:0'}, {'attributes': {'argumentTypes': null, 'overloadedDeclarations': [null], 'referencedDeclaration': 15, 'type': 'uint256', 'value': 'b'}, 'id': 53, 'name': 'Identifier', 'src': '399:1:0'}], 'id': 54, 'name': 'FunctionCall', 'src': '367:34:0'}
t.equals(common.isAbiNamespaceCall(node1), true, 'encode abi')
t.equals(common.isAbiNamespaceCall(node2), true, 'encodePacked abi')
t.equals(common.isAbiNamespaceCall(node3), true, 'encodeWithSelector abi')
t.equals(common.isAbiNamespaceCall(node4), true, 'encodeWithSignature abi')
t.equals(common.isBuiltinFunctionCall(node1), true, 'encode Builtin')
t.equals(common.isBuiltinFunctionCall(node2), true, 'encodePacked Builtin')
t.equals(common.isBuiltinFunctionCall(node3), true, 'encodeWithSelector Builtin')
t.equals(common.isBuiltinFunctionCall(node4), true, 'encodeWithSignature Builtin')
})

Loading…
Cancel
Save