Unverified Commit 062cb9b4 authored by yann300's avatar yann300 Committed by GitHub

Merge pull request #1308 from ethereum/separate_ast_blocks

Separate AST blocks in remix-analyzer tests
parents 4507a805 0e1aa435
{
"attributes": {
"operator": "=",
"type": "uint256"
},
"children": [
{
"attributes": {
"type": "uint256"
},
"children": [
{
"attributes": {
"type": "mapping(address => uint256)",
"value": "c"
},
"id": 61,
"name": "Identifier",
"src": "873:1:0"
},
{
"attributes": {
"member_name": "sender",
"type": "address"
},
"children": [
{
"attributes": {
"type": "msg",
"value": "msg"
},
"id": 62,
"name": "Identifier",
"src": "875:3:0"
}
],
"id": 63,
"name": "MemberAccess",
"src": "875:10:0"
}
],
"id": 64,
"name": "IndexAccess",
"src": "873:13:0"
},
{
"attributes": {
"hexvalue": "30",
"subdenomination": null,
"token": null,
"type": "int_const 0",
"value": "0"
},
"id": 65,
"name": "Literal",
"src": "889:1:0"
}
],
"id": 66,
"name": "Assignment",
"src": "873:17:0"
}
\ No newline at end of file
{
"attributes": {
"member_name": "blockhash",
"type": "function (uint256) returns (bytes32)"
},
"children": [
{
"attributes": {
"type": "block",
"value": "block"
},
"name": "Identifier"
}
],
"name": "MemberAccess"
}
\ No newline at end of file
{
"children":
[
{
"attributes":
{
"argumentTypes": null,
"commonType":
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"operator": "<",
"type": "bool"
},
"children":
[
{
"attributes":
{
"argumentTypes": null,
"overloadedDeclarations":
[
null
],
"referencedDeclaration": 69,
"type": "uint256",
"value": "i"
},
"id": 82,
"name": "Identifier",
"src": "592:1:0"
},
{
"attributes":
{
"argumentTypes": null,
"hexvalue": "3130",
"isConstant": false,
"isLValue": false,
"isPure": true,
"lValueRequested": false,
"subdenomination": null,
"token": "number",
"type": "int_const 10",
"value": "10"
},
"id": 83,
"name": "Literal",
"src": "596:2:0"
}
],
"id": 84,
"name": "BinaryOperation",
"src": "592:6:0"
},
{
"children":
[
{
"children":
[
{
"attributes":
{
"argumentTypes": null,
"isConstant": false,
"isLValue": false,
"isPure": false,
"isStructConstructorCall": false,
"lValueRequested": false,
"names":
[
null
],
"type": "uint256",
"type_conversion": false
},
"children":
[
{
"attributes":
{
"argumentTypes":
[
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
],
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"member_name": "push",
"referencedDeclaration": null,
"type": "function (uint256) returns (uint256)"
},
"children":
[
{
"attributes":
{
"argumentTypes": null,
"overloadedDeclarations":
[
null
],
"referencedDeclaration": 4,
"type": "uint256[] storage ref",
"value": "array"
},
"id": 72,
"name": "Identifier",
"src": "544:5:0"
}
],
"id": 74,
"name": "MemberAccess",
"src": "544:10:0"
},
{
"attributes":
{
"argumentTypes": null,
"overloadedDeclarations":
[
null
],
"referencedDeclaration": 69,
"type": "uint256",
"value": "i"
},
"id": 75,
"name": "Identifier",
"src": "555:1:0"
}
],
"id": 76,
"name": "FunctionCall",
"src": "544:13:0"
}
],
"id": 77,
"name": "ExpressionStatement",
"src": "544:13:0"
},
{
"children":
[
{
"attributes":
{
"argumentTypes": null,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"operator": "++",
"prefix": false,
"type": "uint256"
},
"children":
[
{
"attributes":
{
"argumentTypes": null,
"overloadedDeclarations":
[
null
],
"referencedDeclaration": 69,
"type": "uint256",
"value": "i"
},
"id": 78,
"name": "Identifier",
"src": "571:1:0"
}
],
"id": 79,
"name": "UnaryOperation",
"src": "571:3:0"
}
],
"id": 80,
"name": "ExpressionStatement",
"src": "571:3:0"
}
],
"id": 81,
"name": "Block",
"src": "530:55:0"
}
],
"id": 85,
"name": "DoWhileStatement",
"src": "528:72:0"
}
\ No newline at end of file
{
"attributes": {
"member_name": "info",
"type": "function () payable external returns (uint256)"
},
"children": [
{
"attributes": {
"type": "contract InfoFeed",
"value": "f"
},
"id": 30,
"name": "Identifier",
"src": "405:1:0"
}
],
"id": 32,
"name": "MemberAccess",
"src": "405:6:0"
}
\ No newline at end of file
{
"children":
[
{
"attributes":
{
"assignments":
[
21
]
},
"children":
[
{
"attributes":
{
"constant": false,
"name": "i",
"scope": 39,
"stateVariable": false,
"storageLocation": "default",
"type": "uint256",
"value": null,
"visibility": "internal"
},
"children":
[
{
"attributes":
{
"name": "uint",
"type": "uint256"
},
"id": 20,
"name": "ElementaryTypeName",
"src": "207:4:0"
}
],
"id": 21,
"name": "VariableDeclaration",
"src": "207:6:0"
},
{
"attributes":
{
"argumentTypes": null,
"overloadedDeclarations":
[
null
],
"referencedDeclaration": 17,
"type": "uint256",
"value": "index"
},
"id": 22,
"name": "Identifier",
"src": "216:5:0"
}
],
"id": 23,
"name": "VariableDeclarationStatement",
"src": "207:14:0"
},
{
"attributes":
{
"argumentTypes": null,
"commonType":
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"operator": "<",
"type": "bool"
},
"children":
[
{
"attributes":
{
"argumentTypes": null,
"overloadedDeclarations":
[
null
],
"referencedDeclaration": 21,
"type": "uint256",
"value": "i"
},
"id": 24,
"name": "Identifier",
"src": "223:1:0"
},
{
"attributes":
{
"argumentTypes": null,
"hexvalue": "3130",
"isConstant": false,
"isLValue": false,
"isPure": true,
"lValueRequested": false,
"subdenomination": null,
"token": "number",
"type": "int_const 10",
"value": "10"
},
"id": 25,
"name": "Literal",
"src": "227:2:0"
}
],
"id": 26,
"name": "BinaryOperation",
"src": "223:6:0"
},
{
"children":
[
{
"attributes":
{
"argumentTypes": null,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"operator": "++",
"prefix": false,
"type": "uint256"
},
"children":
[
{
"attributes":
{
"argumentTypes": null,
"overloadedDeclarations":
[
null
],
"referencedDeclaration": 21,
"type": "uint256",
"value": "i"
},
"id": 27,
"name": "Identifier",
"src": "231:1:0"
}
],
"id": 28,
"name": "UnaryOperation",
"src": "231:3:0"
}
],
"id": 29,
"name": "ExpressionStatement",
"src": "231:3:0"
},
{
"children":
[
{
"children":
[
{
"attributes":
{
"argumentTypes": null,
"isConstant": false,
"isLValue": false,
"isPure": false,
"isStructConstructorCall": false,
"lValueRequested": false,
"names":
[
null
],
"type": "uint256",
"type_conversion": false
},
"children":
[
{
"attributes":
{
"argumentTypes":
[
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
],
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"member_name": "push",
"referencedDeclaration": null,
"type": "function (uint256) returns (uint256)"
},
"children":
[
{
"attributes":
{
"argumentTypes": null,
"overloadedDeclarations":
[
null
],
"referencedDeclaration": 4,
"type": "uint256[] storage ref",
"value": "array"
},
"id": 30,
"name": "Identifier",
"src": "250:5:0"
}
],
"id": 32,
"name": "MemberAccess",
"src": "250:10:0"
},
{
"attributes":
{
"argumentTypes": null,
"overloadedDeclarations":
[
null
],
"referencedDeclaration": 21,
"type": "uint256",
"value": "i"
},
"id": 33,
"name": "Identifier",
"src": "261:1:0"
}
],
"id": 34,
"name": "FunctionCall",
"src": "250:13:0"
}
],
"id": 35,
"name": "ExpressionStatement",
"src": "250:13:0"
}
],
"id": 36,
"name": "Block",
"src": "236:38:0"
}
],
"id": 37,
"name": "ForStatement",
"src": "202:72:0"
}
\ No newline at end of file
{
"attributes": {
"constant": false,
"name": "getY",
"payable": false,
"visibility": "public"
},
"children": [
{
"children": [
{
"attributes": {
"name": "z",
"type": "uint256"
},
"children": [
{
"attributes": {
"name": "uint"
},
"name": "ElementaryTypeName"
}
],
"name": "VariableDeclaration"
},
{
"attributes": {
"name": "r",
"type": "bool"
},
"children": [
{
"attributes": {
"name": "bool"
},
"name": "ElementaryTypeName"
}
],
"name": "VariableDeclaration"
}
],
"name": "ParameterList"
},
{
"children": [
{
"attributes": {
"name": "",
"type": "uint256"
},
"children": [
{
"attributes": {
"name": "uint"
},
"id": 34,
"name": "ElementaryTypeName",
"src": "285:4:0"
}
],
"id": 35,
"name": "VariableDeclaration",
"src": "285:4:0"
}
],
"name": "ParameterList"
},
{
"children": [],
"name": "Block"
}
],
"name": "FunctionDefinition"
}
\ No newline at end of file
{
"attributes": {
"constant": true,
"name": "winnerName",
"payable": false,
"visibility": "public"
},
"children": [
{
"children": [
],
"name": "ParameterList"
},
{
"children": [],
"name": "ParameterList"
},
{
"children": [],
"name": "Block"
}
],
"name": "FunctionDefinition"
}
\ No newline at end of file
module.exports = {
localCall: require('./localCall.json'),
thisLocalCall: require('./thisLocalCall.json'),
libCall: require('./libCall.json'),
externalDirect: require('./externalDirect.json'),
superLocal: require('./superLocal.json'),
assignment: require('./assignment.json'),
inlineAssembly: require('./inlineAssembly.json'),
forLoopNode: require('./forLoopNode.json'),
whileLoopNode: require('./whileLoopNode.json'),
doWhileLoopNode: require('./doWhileLoopNode.json'),
stateVariableContractNode: require('./stateVariableContractNode.json'),
functionDefinition: require('./functionDefinition.json'),
fullyQualifiedFunctionDefinition: require('./fullyQualifiedFunctionDefinition.json'),
selfdestruct: require('./selfdestruct.json'),
storageVariableNodes: require('./storageVariableNodes.json'),
lowlevelCall: require('./lowlevelCall.json'),
parameterFunction: require('./parameterFunction.json'),
parameterFunctionCall: require('./parameterFunctionCall.json'),
inheritance: require('./inheritance.json'),
blockHashAccess: require('./blockHashAccess.json')
}
{
"children": [
{
"attributes": {
"name": "r"
},
"id": 7,
"name": "UserDefinedTypeName",
"src": "84:1:0"
}
],
"id": 8,
"name": "InheritanceSpecifier",
"src": "84:1:0"
}
\ No newline at end of file
{
"children": [
],
"id": 21,
"name": "InlineAssembly",
"src": "809:41:0"
}
\ No newline at end of file
{
"attributes": {
"member_name": "insert",
"type": "function (struct Set.Data storage pointer,uint256) returns (bool)"
},
"children": [
{
"attributes": {
"type": "type(library Set)",
"value": "Set"
},
"name": "Identifier"
}
],
"name": "MemberAccess"
}
\ No newline at end of file
{
"attributes": {
"type": "tuple()",
"type_conversion": false
},
"children": [
{
"attributes": {
"type": "function (struct Ballot.Voter storage pointer)",
"value": "bli"
},
"id": 37,
"name": "Identifier",
"src": "540:3:0"
},
{
"attributes": {
"type": "struct Ballot.Voter storage pointer",
"value": "x"
},
"id": 38,
"name": "Identifier",
"src": "544:1:0"
}
],
"id": 39,
"name": "FunctionCall",
"src": "540:6:0"
}
\ No newline at end of file
{
"sendAst": { "name": "MemberAccess",
"children": [
{
"attributes": {
"value": "d",
"type": "address"
}
}],
"attributes": {
"value": "send",
"type": "function (uint256) returns (bool)" }
},
"callAst": { "name": "MemberAccess", "children": [{
"attributes": {
"value": "f",
"type": "address"
}}],
"attributes": {
"member_name": "call",
"type": "function () payable returns (bool)" } },
"callcodeAst": {
"name": "MemberAccess",
"children": [{
"attributes": {
"value": "f",
"type": "address"
}}],
"attributes": {
"member_name": "callcode",
"type": "function () payable returns (bool)" } },
"delegatecallAst": {
"name": "MemberAccess",
"children": [{
"attributes": {
"value": "g",
"type": "address"
}}],
"attributes": {
"member_name": "delegatecall",
"type": "function () returns (bool)" } }
}
\ No newline at end of file
{
"attributes": {
"argumentTypes": null,
"isConstant": false,
"isLValue": false,
"isPure": false,
"isStructConstructorCall": false,
"lValueRequested": false,
"names": [
null
],
"type": "uint256",
"type_conversion": false
},
"children": [
{
"attributes": {
"argumentTypes": [
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
],
"overloadedDeclarations": [
null
],
"referencedDeclaration": 25,
"type": "function (uint256,uint256) pure returns (uint256)",
"value": "f"
},
"id": 34,
"name": "Identifier",
"src": "267:1:0"
},
{
"attributes": {
"argumentTypes": null,
"overloadedDeclarations": [
null
],
"referencedDeclaration": 27,
"type": "uint256",
"value": "x"
},
"id": 35,
"name": "Identifier",
"src": "269:1:0"
},
{
"attributes": {
"argumentTypes": null,
"overloadedDeclarations": [
null
],
"referencedDeclaration": 29,
"type": "uint256",
"value": "y"
},
"id": 36,
"name": "Identifier",
"src": "272:1:0"
}
],
"id": 37,
"name": "FunctionCall",
"src": "267:7:0"
}
\ No newline at end of file
{
"attributes": {
"argumentTypes": null,
"isConstant": false,
"isLValue": false,
"isPure": false,
"isStructConstructorCall": false,
"lValueRequested": false,
"names": [
null
],
"type": "uint256",
"type_conversion": false
},
"children": [
{
"attributes": {
"argumentTypes": [
{
"typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$",
"typeString": "function (uint256,uint256) pure returns (uint256)"
},
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
],
"overloadedDeclarations": [
null
],
"referencedDeclaration": 40,
"type": "function (function (uint256,uint256) pure returns (uint256),uint256,uint256) pure returns (uint256)",
"value": "eval"
},
"id": 49,
"name": "Identifier",
"src": "361:4:0"
},
{
"attributes": {
"argumentTypes": null,
"overloadedDeclarations": [
null
],
"referencedDeclaration": 15,
"type": "function (uint256,uint256) pure returns (uint256)",
"value": "plus"
},
"id": 50,
"name": "Identifier",
"src": "366:4:0"
},
{
"attributes": {
"argumentTypes": null,
"overloadedDeclarations": [
null
],
"referencedDeclaration": 42,
"type": "uint256",
"value": "x"
},
"id": 51,
"name": "Identifier",
"src": "372:1:0"
},
{
"attributes": {
"argumentTypes": null,
"overloadedDeclarations": [
null
],
"referencedDeclaration": 44,
"type": "uint256",
"value": "y"
},
"id": 52,
"name": "Identifier",
"src": "375:1:0"
}
],
"id": 53,
"name": "FunctionCall",
"src": "361:16:0"
}
\ No newline at end of file
{
"attributes": {
"type": "tuple()",
"type_conversion": false
},
"children": [
{
"attributes": {
"type": "function (address)",
"value": "selfdestruct"
},
"name": "Identifier"
},
{
"attributes": {
"type": "address",
"value": "a"
},
"name": "Identifier"
}
],
"name": "FunctionCall"
}
\ No newline at end of file
{
"attributes": {
"fullyImplemented": true,
"isLibrary": false,
"linearizedBaseContracts": [
274
],
"name": "Ballot"
},
"children": [
{
"attributes": {
"name": "Voter"
},
"children": [],
"name": "StructDefinition"
},
{
"attributes": {
"name": "Proposal"
},
"children": [],
"name": "StructDefinition"
},
{
"attributes": {
"name": "chairperson",
"type": "address"
},
"children": [
{
"attributes": {
"name": "address"
},
"name": "ElementaryTypeName"
}
],
"name": "VariableDeclaration"
},
{
"attributes": {
"name": "voters",
"type": "mapping(address => struct Ballot.Voter storage ref)"
},
"children": [
{
"children": [
{
"attributes": {
"name": "address"
},
"name": "ElementaryTypeName"
},
{
"attributes": {
"name": "Voter"
},
"name": "UserDefinedTypeName"
}
],
"name": "Mapping"
}
],
"name": "VariableDeclaration"
},
{
"attributes": {
"name": "proposals",
"type": "struct Ballot.Proposal storage ref[] storage ref"
},
"children": [
{
"children": [
{
"attributes": {
"name": "Proposal"
},
"name": "UserDefinedTypeName"
}
],
"name": "ArrayTypeName"
}
],
"name": "VariableDeclaration"
},
{
"attributes": {
"constant": false,
"name": "Ballot",
"payable": false,
"visibility": "public"
},
"children": [],
"name": "FunctionDefinition"
},
{
"attributes": {
"constant": false,
"name": "giveRightToVote",
"payable": false,
"visibility": "public"
},
"children": [],
"name": "FunctionDefinition"
}
],
"name": "ContractDefinition"
}
\ No newline at end of file
{
"node1": {
"attributes": {
"name": "x",
"type": "struct Ballot.Voter storage pointer"
},
"children": [
{
"attributes": {
"name": "Voter"
},
"id": 43,
"name": "UserDefinedTypeName",
"src": "604:5:0"
}
],
"id": 44,
"name": "VariableDeclaration",
"src": "604:15:0"
},
"node2": {
"attributes": {
"name": "voters",
"type": "mapping(address => struct Ballot.Voter storage ref)"
},
"children": [
{
"children": [
{
"attributes": {
"name": "address"
},
"id": 16,
"name": "ElementaryTypeName",
"src": "235:7:0"
},
{
"attributes": {
"name": "Voter"
},
"id": 17,
"name": "UserDefinedTypeName",
"src": "246:5:0"
}
],
"id": 18,
"name": "Mapping",
"src": "227:25:0"
}
],
"id": 19,
"name": "VariableDeclaration",
"src": "227:32:0"
},
"node3": {
"attributes": {
"name": "voters",
"type": "bytes32"
},
"children": [
{
"attributes": {
"name": "bytes"
},
"id": 16,
"name": "ElementaryTypeName",
"src": "235:7:0"
}
],
"id": 19,
"name": "VariableDeclaration",
"src": "227:32:0"
}
}
\ No newline at end of file
{
"attributes": {
"member_name": "duper",
"type": "function ()"
},
"children": [
{
"attributes": {
"type": "contract super a",
"value": "super"
},
"name": "Identifier"
}
],
"name": "MemberAccess"
}
\ No newline at end of file
{
"name": "MemberAccess",
"children": [ {
"attributes": {
"value": "this",
"type": "contract test" },
"name": "Identifier" } ],
"attributes": {
"value": "b",
"type": "function (bytes32,address) returns (bool)" } }
\ No newline at end of file
{
"children":
[
{
"attributes":
{
"argumentTypes": null,
"commonType":
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"operator": "<",
"type": "bool"
},
"children":
[
{
"attributes":
{
"argumentTypes": null,
"overloadedDeclarations":
[
null
],
"referencedDeclaration": 45,
"type": "uint256",
"value": "i"
},
"id": 48,
"name": "Identifier",
"src": "372:1:0"
},
{
"attributes":
{
"argumentTypes": null,
"hexvalue": "3130",
"isConstant": false,
"isLValue": false,
"isPure": true,
"lValueRequested": false,
"subdenomination": null,
"token": "number",
"type": "int_const 10",
"value": "10"
},
"id": 49,
"name": "Literal",
"src": "376:2:0"
}
],
"id": 50,
"name": "BinaryOperation",
"src": "372:6:0"
},
{
"children":
[
{
"children":
[
{
"attributes":
{
"argumentTypes": null,
"isConstant": false,
"isLValue": false,
"isPure": false,
"isStructConstructorCall": false,
"lValueRequested": false,
"names":
[
null
],
"type": "uint256",
"type_conversion": false
},
"children":
[
{
"attributes":
{
"argumentTypes":
[
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
],
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"member_name": "push",
"referencedDeclaration": null,
"type": "function (uint256) returns (uint256)"
},
"children":
[
{
"attributes":
{
"argumentTypes": null,
"overloadedDeclarations":
[
null
],
"referencedDeclaration": 4,
"type": "uint256[] storage ref",
"value": "array"
},
"id": 51,
"name": "Identifier",
"src": "394:5:0"
}
],
"id": 53,
"name": "MemberAccess",
"src": "394:10:0"
},
{
"attributes":
{
"argumentTypes": null,
"overloadedDeclarations":
[
null
],
"referencedDeclaration": 45,
"type": "uint256",
"value": "i"
},
"id": 54,
"name": "Identifier",
"src": "405:1:0"
}
],
"id": 55,
"name": "FunctionCall",
"src": "394:13:0"
}
],
"id": 56,
"name": "ExpressionStatement",
"src": "394:13:0"
},
{
"children":
[
{
"attributes":
{
"argumentTypes": null,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"operator": "++",
"prefix": false,
"type": "uint256"
},
"children":
[
{
"attributes":
{
"argumentTypes": null,
"overloadedDeclarations":
[
null
],
"referencedDeclaration": 45,
"type": "uint256",
"value": "i"
},
"id": 57,
"name": "Identifier",
"src": "421:1:0"
}
],
"id": 58,
"name": "UnaryOperation",
"src": "421:3:0"
}
],
"id": 59,
"name": "ExpressionStatement",
"src": "421:3:0"
}
],
"id": 60,
"name": "Block",
"src": "380:55:0"
}
],
"id": 61,
"name": "WhileStatement",
"src": "365:70:0"
}
\ No newline at end of file
var test = require('tape') var test = require('tape')
var common = require('../../src/solidity-analyzer/modules/staticAnalysisCommon') var common = require('../../src/solidity-analyzer/modules/staticAnalysisCommon')
var { localCall, thisLocalCall, libCall, externalDirect, superLocal, assignment,
inlineAssembly, forLoopNode, whileLoopNode, doWhileLoopNode, stateVariableContractNode,
functionDefinition, fullyQualifiedFunctionDefinition, selfdestruct, storageVariableNodes,
lowlevelCall, parameterFunction, parameterFunctionCall, inheritance, blockHashAccess } = require('./astBlocks')
function escapeRegExp (str) { function escapeRegExp (str) {
return str.replace(/[-[\]/{}()+?.\\^$|]/g, '\\$&') return str.replace(/[-[\]/{}()+?.\\^$|]/g, '\\$&')
...@@ -157,72 +160,6 @@ test('staticAnalysisCommon.getType', function (t) { ...@@ -157,72 +160,6 @@ test('staticAnalysisCommon.getType', function (t) {
test('staticAnalysisCommon.getFunctionCallType', function (t) { test('staticAnalysisCommon.getFunctionCallType', function (t) {
t.plan(5) t.plan(5)
var localCall = {
'attributes': {
'type': 'tuple()',
'type_conversion': false
},
'children': [
{
'attributes': {
'type': 'function (struct Ballot.Voter storage pointer)',
'value': 'bli'
},
'id': 37,
'name': 'Identifier',
'src': '540:3:0'
},
{
'attributes': {
'type': 'struct Ballot.Voter storage pointer',
'value': 'x'
},
'id': 38,
'name': 'Identifier',
'src': '544:1:0'
}
],
'id': 39,
'name': 'FunctionCall',
'src': '540:6:0'
}
var thisLocalCall = { name: 'MemberAccess', children: [ { attributes: { value: 'this', type: 'contract test' }, name: 'Identifier' } ], attributes: { value: 'b', type: 'function (bytes32,address) returns (bool)' } }
var externalDirect = {
attributes: {
member_name: 'info',
type: 'function () payable external returns (uint256)'
},
children: [
{
attributes: {
type: 'contract InfoFeed',
value: 'f'
},
id: 30,
name: 'Identifier',
src: '405:1:0'
}
],
id: 32,
name: 'MemberAccess',
src: '405:6:0'
}
var libCall = {
'attributes': {
'member_name': 'insert',
'type': 'function (struct Set.Data storage pointer,uint256) returns (bool)'
},
'children': [
{
'attributes': {
'type': 'type(library Set)',
'value': 'Set'
},
'name': 'Identifier'
}
],
'name': 'MemberAccess'
}
t.equal(common.getFunctionCallType(libCall), 'function (struct Set.Data storage pointer,uint256) returns (bool)', 'this lib call returns correct type') t.equal(common.getFunctionCallType(libCall), 'function (struct Set.Data storage pointer,uint256) returns (bool)', 'this lib call returns correct type')
t.equal(common.getFunctionCallType(thisLocalCall), 'function (bytes32,address) returns (bool)', 'this local call returns correct type') t.equal(common.getFunctionCallType(thisLocalCall), 'function (bytes32,address) returns (bool)', 'this local call returns correct type')
t.equal(common.getFunctionCallType(externalDirect), 'function () payable external returns (uint256)', 'external direct call returns correct type') t.equal(common.getFunctionCallType(externalDirect), 'function () payable external returns (uint256)', 'external direct call returns correct type')
...@@ -232,75 +169,6 @@ test('staticAnalysisCommon.getFunctionCallType', function (t) { ...@@ -232,75 +169,6 @@ test('staticAnalysisCommon.getFunctionCallType', function (t) {
test('staticAnalysisCommon.getEffectedVariableName', function (t) { test('staticAnalysisCommon.getEffectedVariableName', function (t) {
t.plan(3) t.plan(3)
var assignment = {
'attributes': {
'operator': '=',
'type': 'uint256'
},
'children': [
{
'attributes': {
'type': 'uint256'
},
'children': [
{
'attributes': {
'type': 'mapping(address => uint256)',
'value': 'c'
},
'id': 61,
'name': 'Identifier',
'src': '873:1:0'
},
{
'attributes': {
'member_name': 'sender',
'type': 'address'
},
'children': [
{
'attributes': {
'type': 'msg',
'value': 'msg'
},
'id': 62,
'name': 'Identifier',
'src': '875:3:0'
}
],
'id': 63,
'name': 'MemberAccess',
'src': '875:10:0'
}
],
'id': 64,
'name': 'IndexAccess',
'src': '873:13:0'
},
{
'attributes': {
'hexvalue': '30',
'subdenomination': null,
'token': null,
'type': 'int_const 0',
'value': '0'
},
'id': 65,
'name': 'Literal',
'src': '889:1:0'
}
],
'id': 66,
'name': 'Assignment',
'src': '873:17:0'
}
var inlineAssembly = {
'children': [
],
'id': 21,
'name': 'InlineAssembly',
'src': '809:41:0'
}
t.throws(() => common.getEffectedVariableName(inlineAssembly), 'staticAnalysisCommon.js: not an effect Node or inline assembly', 'get from inline assembly should throw') t.throws(() => common.getEffectedVariableName(inlineAssembly), 'staticAnalysisCommon.js: not an effect Node or inline assembly', 'get from inline assembly should throw')
t.ok(common.getEffectedVariableName(assignment) === 'c', 'get right name for assignment') t.ok(common.getEffectedVariableName(assignment) === 'c', 'get right name for assignment')
t.throws(() => common.getEffectedVariableName({ name: 'MemberAccess' }), undefined, 'should throw on all other nodes') t.throws(() => common.getEffectedVariableName({ name: 'MemberAccess' }), undefined, 'should throw on all other nodes')
...@@ -308,56 +176,6 @@ test('staticAnalysisCommon.getEffectedVariableName', function (t) { ...@@ -308,56 +176,6 @@ test('staticAnalysisCommon.getEffectedVariableName', function (t) {
test('staticAnalysisCommon.getLocalCallName', function (t) { test('staticAnalysisCommon.getLocalCallName', function (t) {
t.plan(3) t.plan(3)
var localCall = {
'attributes': {
'type': 'tuple()',
'type_conversion': false
},
'children': [
{
'attributes': {
'type': 'function (struct Ballot.Voter storage pointer)',
'value': 'bli'
},
'id': 37,
'name': 'Identifier',
'src': '540:3:0'
},
{
'attributes': {
'type': 'struct Ballot.Voter storage pointer',
'value': 'x'
},
'id': 38,
'name': 'Identifier',
'src': '544:1:0'
}
],
'id': 39,
'name': 'FunctionCall',
'src': '540:6:0'
}
var thisLocalCall = { name: 'MemberAccess', children: [ { attributes: { value: 'this', type: 'contract test' }, name: 'Identifier' } ], attributes: { value: 'b', type: 'function (bytes32,address) returns (bool)' } }
var externalDirect = {
attributes: {
member_name: 'info',
type: 'function () payable external returns (uint256)'
},
children: [
{
attributes: {
type: 'contract InfoFeed',
value: 'f'
},
id: 30,
name: 'Identifier',
src: '405:1:0'
}
],
id: 32,
name: 'MemberAccess',
src: '405:6:0'
}
t.ok(common.getLocalCallName(localCall) === 'bli', 'getLocal call name from node') t.ok(common.getLocalCallName(localCall) === 'bli', 'getLocal call name from node')
t.throws(() => common.getLocalCallName(externalDirect), undefined, 'throws on other nodes') t.throws(() => common.getLocalCallName(externalDirect), undefined, 'throws on other nodes')
t.throws(() => common.getLocalCallName(thisLocalCall), undefined, 'throws on other nodes') t.throws(() => common.getLocalCallName(thisLocalCall), undefined, 'throws on other nodes')
...@@ -365,56 +183,6 @@ test('staticAnalysisCommon.getLocalCallName', function (t) { ...@@ -365,56 +183,6 @@ test('staticAnalysisCommon.getLocalCallName', function (t) {
test('staticAnalysisCommon.getThisLocalCallName', function (t) { test('staticAnalysisCommon.getThisLocalCallName', function (t) {
t.plan(3) t.plan(3)
var localCall = {
'attributes': {
'type': 'tuple()',
'type_conversion': false
},
'children': [
{
'attributes': {
'type': 'function (struct Ballot.Voter storage pointer)',
'value': 'bli'
},
'id': 37,
'name': 'Identifier',
'src': '540:3:0'
},
{
'attributes': {
'type': 'struct Ballot.Voter storage pointer',
'value': 'x'
},
'id': 38,
'name': 'Identifier',
'src': '544:1:0'
}
],
'id': 39,
'name': 'FunctionCall',
'src': '540:6:0'
}
var thisLocalCall = { name: 'MemberAccess', children: [ { attributes: { value: 'this', type: 'contract test' }, name: 'Identifier' } ], attributes: { value: 'b', type: 'function (bytes32,address) returns (bool)' } }
var externalDirect = {
attributes: {
member_name: 'info',
type: 'function () payable external returns (uint256)'
},
children: [
{
attributes: {
type: 'contract InfoFeed',
value: 'f'
},
id: 30,
name: 'Identifier',
src: '405:1:0'
}
],
id: 32,
name: 'MemberAccess',
src: '405:6:0'
}
t.ok(common.getThisLocalCallName(thisLocalCall) === 'b', 'get this Local call name from node') t.ok(common.getThisLocalCallName(thisLocalCall) === 'b', 'get this Local call name from node')
t.throws(() => common.getThisLocalCallName(externalDirect), undefined, 'throws on other nodes') t.throws(() => common.getThisLocalCallName(externalDirect), undefined, 'throws on other nodes')
t.throws(() => common.getThisLocalCallName(localCall), undefined, 'throws on other nodes') t.throws(() => common.getThisLocalCallName(localCall), undefined, 'throws on other nodes')
...@@ -422,72 +190,6 @@ test('staticAnalysisCommon.getThisLocalCallName', function (t) { ...@@ -422,72 +190,6 @@ test('staticAnalysisCommon.getThisLocalCallName', function (t) {
test('staticAnalysisCommon.getSuperLocalCallName', function (t) { test('staticAnalysisCommon.getSuperLocalCallName', function (t) {
t.plan(4) t.plan(4)
var superLocal = {
'attributes': {
'member_name': 'duper',
'type': 'function ()'
},
'children': [
{
'attributes': {
'type': 'contract super a',
'value': 'super'
},
'name': 'Identifier'
}
],
'name': 'MemberAccess'
}
var localCall = {
'attributes': {
'type': 'tuple()',
'type_conversion': false
},
'children': [
{
'attributes': {
'type': 'function (struct Ballot.Voter storage pointer)',
'value': 'bli'
},
'id': 37,
'name': 'Identifier',
'src': '540:3:0'
},
{
'attributes': {
'type': 'struct Ballot.Voter storage pointer',
'value': 'x'
},
'id': 38,
'name': 'Identifier',
'src': '544:1:0'
}
],
'id': 39,
'name': 'FunctionCall',
'src': '540:6:0'
}
var thisLocalCall = { name: 'MemberAccess', children: [ { attributes: { value: 'this', type: 'contract test' }, name: 'Identifier' } ], attributes: { value: 'b', type: 'function (bytes32,address) returns (bool)' } }
var externalDirect = {
attributes: {
member_name: 'info',
type: 'function () payable external returns (uint256)'
},
children: [
{
attributes: {
type: 'contract InfoFeed',
value: 'f'
},
id: 30,
name: 'Identifier',
src: '405:1:0'
}
],
id: 32,
name: 'MemberAccess',
src: '405:6:0'
}
t.equal(common.getSuperLocalCallName(superLocal), 'duper', 'get local name from super local call') t.equal(common.getSuperLocalCallName(superLocal), 'duper', 'get local name from super local call')
t.throws(() => common.getSuperLocalCallName(thisLocalCall), 'throws on other nodes') t.throws(() => common.getSuperLocalCallName(thisLocalCall), 'throws on other nodes')
t.throws(() => common.getSuperLocalCallName(externalDirect), undefined, 'throws on other nodes') t.throws(() => common.getSuperLocalCallName(externalDirect), undefined, 'throws on other nodes')
...@@ -496,57 +198,6 @@ test('staticAnalysisCommon.getSuperLocalCallName', function (t) { ...@@ -496,57 +198,6 @@ test('staticAnalysisCommon.getSuperLocalCallName', function (t) {
test('staticAnalysisCommon.getExternalDirectCallContractName', function (t) { test('staticAnalysisCommon.getExternalDirectCallContractName', function (t) {
t.plan(3) t.plan(3)
var localCall = {
'attributes': {
'type': 'tuple()',
'type_conversion': false
},
'children': [
{
'attributes': {
'type': 'function (struct Ballot.Voter storage pointer)',
'value': 'bli'
},
'id': 37,
'name': 'Identifier',
'src': '540:3:0'
},
{
'attributes': {
'type': 'struct Ballot.Voter storage pointer',
'value': 'x'
},
'id': 38,
'name': 'Identifier',
'src': '544:1:0'
}
],
'id': 39,
'name': 'FunctionCall',
'src': '540:6:0'
}
var thisLocalCall = { name: 'MemberAccess', children: [ { attributes: { value: 'this', type: 'contract test' }, name: 'Identifier' } ], attributes: { value: 'b', type: 'function (bytes32,address) returns (bool)' } }
var externalDirect = {
attributes: {
member_name: 'info',
type: 'function () payable external returns (uint256)'
},
children: [
{
attributes: {
type: 'contract InfoFeed',
value: 'f'
},
id: 30,
name: 'Identifier',
src: '405:1:0'
}
],
id: 32,
name: 'MemberAccess',
src: '405:6:0'
}
t.ok(common.getExternalDirectCallContractName(externalDirect) === 'InfoFeed', 'external direct call contract name from node') t.ok(common.getExternalDirectCallContractName(externalDirect) === 'InfoFeed', 'external direct call contract name from node')
t.throws(() => common.getExternalDirectCallContractName(thisLocalCall), undefined, 'throws on other nodes') t.throws(() => common.getExternalDirectCallContractName(thisLocalCall), undefined, 'throws on other nodes')
t.throws(() => common.getExternalDirectCallContractName(localCall), undefined, 'throws on other nodes') t.throws(() => common.getExternalDirectCallContractName(localCall), undefined, 'throws on other nodes')
...@@ -554,56 +205,6 @@ test('staticAnalysisCommon.getExternalDirectCallContractName', function (t) { ...@@ -554,56 +205,6 @@ test('staticAnalysisCommon.getExternalDirectCallContractName', function (t) {
test('staticAnalysisCommon.getThisLocalCallContractName', function (t) { test('staticAnalysisCommon.getThisLocalCallContractName', function (t) {
t.plan(3) t.plan(3)
var localCall = {
'attributes': {
'type': 'tuple()',
'type_conversion': false
},
'children': [
{
'attributes': {
'type': 'function (struct Ballot.Voter storage pointer)',
'value': 'bli'
},
'id': 37,
'name': 'Identifier',
'src': '540:3:0'
},
{
'attributes': {
'type': 'struct Ballot.Voter storage pointer',
'value': 'x'
},
'id': 38,
'name': 'Identifier',
'src': '544:1:0'
}
],
'id': 39,
'name': 'FunctionCall',
'src': '540:6:0'
}
var thisLocalCall = { name: 'MemberAccess', children: [ { attributes: { value: 'this', type: 'contract test' }, name: 'Identifier' } ], attributes: { value: 'b', type: 'function (bytes32,address) returns (bool)' } }
var externalDirect = {
attributes: {
member_name: 'info',
type: 'function () payable external returns (uint256)'
},
children: [
{
attributes: {
type: 'contract InfoFeed',
value: 'f'
},
id: 30,
name: 'Identifier',
src: '405:1:0'
}
],
id: 32,
name: 'MemberAccess',
src: '405:6:0'
}
t.ok(common.getThisLocalCallContractName(thisLocalCall) === 'test', 'this local call contract name from node') t.ok(common.getThisLocalCallContractName(thisLocalCall) === 'test', 'this local call contract name from node')
t.throws(() => common.getThisLocalCallContractName(localCall), undefined, 'throws on other nodes') t.throws(() => common.getThisLocalCallContractName(localCall), undefined, 'throws on other nodes')
t.throws(() => common.getThisLocalCallContractName(externalDirect), undefined, 'throws on other nodes') t.throws(() => common.getThisLocalCallContractName(externalDirect), undefined, 'throws on other nodes')
...@@ -611,56 +212,6 @@ test('staticAnalysisCommon.getThisLocalCallContractName', function (t) { ...@@ -611,56 +212,6 @@ test('staticAnalysisCommon.getThisLocalCallContractName', function (t) {
test('staticAnalysisCommon.getExternalDirectCallMemberName', function (t) { test('staticAnalysisCommon.getExternalDirectCallMemberName', function (t) {
t.plan(3) t.plan(3)
var localCall = {
'attributes': {
'type': 'tuple()',
'type_conversion': false
},
'children': [
{
'attributes': {
'type': 'function (struct Ballot.Voter storage pointer)',
'value': 'bli'
},
'id': 37,
'name': 'Identifier',
'src': '540:3:0'
},
{
'attributes': {
'type': 'struct Ballot.Voter storage pointer',
'value': 'x'
},
'id': 38,
'name': 'Identifier',
'src': '544:1:0'
}
],
'id': 39,
'name': 'FunctionCall',
'src': '540:6:0'
}
var thisLocalCall = { name: 'MemberAccess', children: [ { attributes: { value: 'this', type: 'contract test' }, name: 'Identifier' } ], attributes: { value: 'b', type: 'function (bytes32,address) returns (bool)' } }
var externalDirect = {
attributes: {
member_name: 'info',
type: 'function () payable external returns (uint256)'
},
children: [
{
attributes: {
type: 'contract InfoFeed',
value: 'f'
},
id: 30,
name: 'Identifier',
src: '405:1:0'
}
],
id: 32,
name: 'MemberAccess',
src: '405:6:0'
}
t.ok(common.getExternalDirectCallMemberName(externalDirect) === 'info', 'external direct call name from node') t.ok(common.getExternalDirectCallMemberName(externalDirect) === 'info', 'external direct call name from node')
t.throws(() => common.getExternalDirectCallMemberName(thisLocalCall), undefined, 'throws on other nodes') t.throws(() => common.getExternalDirectCallMemberName(thisLocalCall), undefined, 'throws on other nodes')
t.throws(() => common.getExternalDirectCallMemberName(localCall), undefined, 'throws on other nodes') t.throws(() => common.getExternalDirectCallMemberName(localCall), undefined, 'throws on other nodes')
...@@ -682,163 +233,21 @@ test('staticAnalysisCommon.getFunctionDefinitionName', function (t) { ...@@ -682,163 +233,21 @@ test('staticAnalysisCommon.getFunctionDefinitionName', function (t) {
test('staticAnalysisCommon.getInheritsFromName', function (t) { test('staticAnalysisCommon.getInheritsFromName', function (t) {
t.plan(2) t.plan(2)
var inh = { t.ok(common.getInheritsFromName(inheritance) === 'r', 'returns right contract name')
'children': [
{
'attributes': {
'name': 'r'
},
'id': 7,
'name': 'UserDefinedTypeName',
'src': '84:1:0'
}
],
'id': 8,
'name': 'InheritanceSpecifier',
'src': '84:1:0'
}
t.ok(common.getInheritsFromName(inh) === 'r', 'returns right contract name')
t.throws(() => common.getInheritsFromName({ name: 'ElementaryTypeName' }), undefined, 'throws on other nodes') t.throws(() => common.getInheritsFromName({ name: 'ElementaryTypeName' }), undefined, 'throws on other nodes')
}) })
test('staticAnalysisCommon.getDeclaredVariableName', function (t) { test('staticAnalysisCommon.getDeclaredVariableName', function (t) {
t.plan(2) t.plan(2)
var node1 = { t.ok(common.getDeclaredVariableName(storageVariableNodes.node1) === 'x', 'extract right variable name')
'attributes': { let node1 = JSON.parse(JSON.stringify(storageVariableNodes))
'name': 'x', node1.node1.name = 'FunctionCall'
'type': 'struct Ballot.Voter storage pointer'
},
'children': [
{
'attributes': {
'name': 'Voter'
},
'id': 43,
'name': 'UserDefinedTypeName',
'src': '604:5:0'
}
],
'id': 44,
'name': 'VariableDeclaration',
'src': '604:15:0'
}
t.ok(common.getDeclaredVariableName(node1) === 'x', 'extract right variable name')
node1.name = 'FunctionCall'
t.throws(() => common.getDeclaredVariableName(node1) === 'x', undefined, 'throw if wrong node') t.throws(() => common.getDeclaredVariableName(node1) === 'x', undefined, 'throw if wrong node')
}) })
test('staticAnalysisCommon.getStateVariableDeclarationsFormContractNode', function (t) { test('staticAnalysisCommon.getStateVariableDeclarationsFormContractNode', function (t) {
t.plan(4) t.plan(4)
var contract = { var res = common.getStateVariableDeclarationsFormContractNode(stateVariableContractNode).map(common.getDeclaredVariableName)
'attributes': {
'fullyImplemented': true,
'isLibrary': false,
'linearizedBaseContracts': [
274
],
'name': 'Ballot'
},
'children': [
{
'attributes': {
'name': 'Voter'
},
'children': [],
'name': 'StructDefinition'
},
{
'attributes': {
'name': 'Proposal'
},
'children': [],
'name': 'StructDefinition'
},
{
'attributes': {
'name': 'chairperson',
'type': 'address'
},
'children': [
{
'attributes': {
'name': 'address'
},
'name': 'ElementaryTypeName'
}
],
'name': 'VariableDeclaration'
},
{
'attributes': {
'name': 'voters',
'type': 'mapping(address => struct Ballot.Voter storage ref)'
},
'children': [
{
'children': [
{
'attributes': {
'name': 'address'
},
'name': 'ElementaryTypeName'
},
{
'attributes': {
'name': 'Voter'
},
'name': 'UserDefinedTypeName'
}
],
'name': 'Mapping'
}
],
'name': 'VariableDeclaration'
},
{
'attributes': {
'name': 'proposals',
'type': 'struct Ballot.Proposal storage ref[] storage ref'
},
'children': [
{
'children': [
{
'attributes': {
'name': 'Proposal'
},
'name': 'UserDefinedTypeName'
}
],
'name': 'ArrayTypeName'
}
],
'name': 'VariableDeclaration'
},
{
'attributes': {
'constant': false,
'name': 'Ballot',
'payable': false,
'visibility': 'public'
},
'children': [],
'name': 'FunctionDefinition'
},
{
'attributes': {
'constant': false,
'name': 'giveRightToVote',
'payable': false,
'visibility': 'public'
},
'children': [],
'name': 'FunctionDefinition'
}
],
'name': 'ContractDefinition'
}
var res = common.getStateVariableDeclarationsFormContractNode(contract).map(common.getDeclaredVariableName)
t.ok(res[0] === 'chairperson', 'var 1 should be ') t.ok(res[0] === 'chairperson', 'var 1 should be ')
t.ok(res[1] === 'voters', 'var 2 should be ') t.ok(res[1] === 'voters', 'var 2 should be ')
t.ok(res[2] === 'proposals', 'var 3 should be ') t.ok(res[2] === 'proposals', 'var 3 should be ')
...@@ -847,86 +256,12 @@ test('staticAnalysisCommon.getStateVariableDeclarationsFormContractNode', functi ...@@ -847,86 +256,12 @@ test('staticAnalysisCommon.getStateVariableDeclarationsFormContractNode', functi
test('staticAnalysisCommon.getFunctionOrModifierDefinitionParameterPart', function (t) { test('staticAnalysisCommon.getFunctionOrModifierDefinitionParameterPart', function (t) {
t.plan(2) t.plan(2)
var funDef = { t.ok(common.helpers.nodeType(common.getFunctionOrModifierDefinitionParameterPart(functionDefinition), 'ParameterList'), 'should return a parameterList')
'attributes': {
'constant': true,
'name': 'winnerName',
'payable': false,
'visibility': 'public'
},
'children': [
{
'children': [
],
'name': 'ParameterList'
},
{
'children': [],
'name': 'ParameterList'
},
{
'children': [],
'name': 'Block'
}
],
'name': 'FunctionDefinition'
}
t.ok(common.helpers.nodeType(common.getFunctionOrModifierDefinitionParameterPart(funDef), 'ParameterList'), 'should return a parameterList')
t.throws(() => common.getFunctionOrModifierDefinitionParameterPart({ name: 'SourceUnit' }), undefined, 'throws on other nodes') t.throws(() => common.getFunctionOrModifierDefinitionParameterPart({ name: 'SourceUnit' }), undefined, 'throws on other nodes')
}) })
test('staticAnalysisCommon.getFunctionCallTypeParameterType', function (t) { test('staticAnalysisCommon.getFunctionCallTypeParameterType', function (t) {
t.plan(4) t.plan(4)
var localCall = {
'attributes': {
'type': 'tuple()',
'type_conversion': false
},
'children': [
{
'attributes': {
'type': 'function (struct Ballot.Voter storage pointer)',
'value': 'bli'
},
'id': 37,
'name': 'Identifier',
'src': '540:3:0'
},
{
'attributes': {
'type': 'struct Ballot.Voter storage pointer',
'value': 'x'
},
'id': 38,
'name': 'Identifier',
'src': '544:1:0'
}
],
'id': 39,
'name': 'FunctionCall',
'src': '540:6:0'
}
var thisLocalCall = { name: 'MemberAccess', children: [ { attributes: { value: 'this', type: 'contract test' }, name: 'Identifier' } ], attributes: { value: 'b', type: 'function (bytes32,address) returns (bool)' } }
var externalDirect = {
attributes: {
member_name: 'info',
type: 'function () payable external returns (uint256)'
},
children: [
{
attributes: {
type: 'contract InfoFeed',
value: 'f'
},
id: 30,
name: 'Identifier',
src: '405:1:0'
}
],
id: 32,
name: 'MemberAccess',
src: '405:6:0'
}
t.ok(common.getFunctionCallTypeParameterType(thisLocalCall) === 'bytes32,address', 'this local call returns correct type') t.ok(common.getFunctionCallTypeParameterType(thisLocalCall) === 'bytes32,address', 'this local call returns correct type')
t.ok(common.getFunctionCallTypeParameterType(externalDirect) === '', 'external direct call returns correct type') t.ok(common.getFunctionCallTypeParameterType(externalDirect) === '', 'external direct call returns correct type')
t.ok(common.getFunctionCallTypeParameterType(localCall) === 'struct Ballot.Voter storage pointer', 'local call returns correct type') t.ok(common.getFunctionCallTypeParameterType(localCall) === 'struct Ballot.Voter storage pointer', 'local call returns correct type')
...@@ -935,102 +270,19 @@ test('staticAnalysisCommon.getFunctionCallTypeParameterType', function (t) { ...@@ -935,102 +270,19 @@ test('staticAnalysisCommon.getFunctionCallTypeParameterType', function (t) {
test('staticAnalysisCommon.getLibraryCallContractName', function (t) { test('staticAnalysisCommon.getLibraryCallContractName', function (t) {
t.plan(2) t.plan(2)
var node = { t.equal(common.getLibraryCallContractName(libCall), 'Set', 'should return correct contract name')
'attributes': {
'member_name': 'insert',
'type': 'function (struct Set.Data storage pointer,uint256) returns (bool)'
},
'children': [
{
'attributes': {
'type': 'type(library Set)',
'value': 'Set'
},
'name': 'Identifier'
}
],
'name': 'MemberAccess'
}
t.equal(common.getLibraryCallContractName(node), 'Set', 'should return correct contract name')
t.throws(() => common.getLibraryCallContractName({ name: 'Identifier' }), undefined, 'should throw on wrong node') t.throws(() => common.getLibraryCallContractName({ name: 'Identifier' }), undefined, 'should throw on wrong node')
}) })
test('staticAnalysisCommon.getLibraryCallMemberName', function (t) { test('staticAnalysisCommon.getLibraryCallMemberName', function (t) {
t.plan(2) t.plan(2)
var node = { t.equal(common.getLibraryCallMemberName(libCall), 'insert', 'should return correct member name')
'attributes': {
'member_name': 'insert',
'type': 'function (struct Set.Data storage pointer,uint256) returns (bool)'
},
'children': [
{
'attributes': {
'type': 'type(library Set)',
'value': 'Set'
},
'name': 'Identifier'
}
],
'name': 'MemberAccess'
}
t.equal(common.getLibraryCallMemberName(node), 'insert', 'should return correct member name')
t.throws(() => common.getLibraryCallMemberName({ name: 'Identifier' }), undefined, 'should throw on wrong node') t.throws(() => common.getLibraryCallMemberName({ name: 'Identifier' }), undefined, 'should throw on wrong node')
}) })
test('staticAnalysisCommon.getFullQualifiedFunctionCallIdent', function (t) { test('staticAnalysisCommon.getFullQualifiedFunctionCallIdent', function (t) {
t.plan(4) t.plan(4)
var contract = { name: 'ContractDefinition', attributes: { name: 'baz' } } var contract = { name: 'ContractDefinition', attributes: { name: 'baz' } }
var localCall = {
'attributes': {
'type': 'tuple()',
'type_conversion': false
},
'children': [
{
'attributes': {
'type': 'function (struct Ballot.Voter storage pointer)',
'value': 'bli'
},
'id': 37,
'name': 'Identifier',
'src': '540:3:0'
},
{
'attributes': {
'type': 'struct Ballot.Voter storage pointer',
'value': 'x'
},
'id': 38,
'name': 'Identifier',
'src': '544:1:0'
}
],
'id': 39,
'name': 'FunctionCall',
'src': '540:6:0'
}
var thisLocalCall = { name: 'MemberAccess', children: [ { attributes: { value: 'this', type: 'contract test' }, name: 'Identifier' } ], attributes: { value: 'b', type: 'function (bytes32,address) returns (bool)' } }
var externalDirect = {
attributes: {
member_name: 'info',
type: 'function () payable external returns (uint256)'
},
children: [
{
attributes: {
type: 'contract InfoFeed',
value: 'f'
},
id: 30,
name: 'Identifier',
src: '405:1:0'
}
],
id: 32,
name: 'MemberAccess',
src: '405:6:0'
}
t.ok(common.getFullQualifiedFunctionCallIdent(contract, thisLocalCall) === 'test.b(bytes32,address)', 'this local call returns correct type') t.ok(common.getFullQualifiedFunctionCallIdent(contract, thisLocalCall) === 'test.b(bytes32,address)', 'this local call returns correct type')
t.ok(common.getFullQualifiedFunctionCallIdent(contract, externalDirect) === 'InfoFeed.info()', 'external direct call returns correct type') t.ok(common.getFullQualifiedFunctionCallIdent(contract, externalDirect) === 'InfoFeed.info()', 'external direct call returns correct type')
t.ok(common.getFullQualifiedFunctionCallIdent(contract, localCall) === 'baz.bli(struct Ballot.Voter storage pointer)', 'local call returns correct type') t.ok(common.getFullQualifiedFunctionCallIdent(contract, localCall) === 'baz.bli(struct Ballot.Voter storage pointer)', 'local call returns correct type')
...@@ -1040,763 +292,16 @@ test('staticAnalysisCommon.getFullQualifiedFunctionCallIdent', function (t) { ...@@ -1040,763 +292,16 @@ test('staticAnalysisCommon.getFullQualifiedFunctionCallIdent', function (t) {
test('staticAnalysisCommon.getFullQuallyfiedFuncDefinitionIdent', function (t) { test('staticAnalysisCommon.getFullQuallyfiedFuncDefinitionIdent', function (t) {
t.plan(3) t.plan(3)
var contract = { name: 'ContractDefinition', attributes: { name: 'baz' } } var contract = { name: 'ContractDefinition', attributes: { name: 'baz' } }
var funDef = { t.ok(common.getFullQuallyfiedFuncDefinitionIdent(contract, fullyQualifiedFunctionDefinition, ['uint256', 'bool']) === 'baz.getY(uint256,bool)', 'creates right signature')
'attributes': {
'constant': false,
'name': 'getY',
'payable': false,
'visibility': 'public'
},
'children': [
{
'children': [
{
'attributes': {
'name': 'z',
'type': 'uint256'
},
'children': [
{
'attributes': {
'name': 'uint'
},
'name': 'ElementaryTypeName'
}
],
'name': 'VariableDeclaration'
},
{
'attributes': {
'name': 'r',
'type': 'bool'
},
'children': [
{
'attributes': {
'name': 'bool'
},
'name': 'ElementaryTypeName'
}
],
'name': 'VariableDeclaration'
}
],
'name': 'ParameterList'
},
{
'children': [
{
'attributes': {
'name': '',
'type': 'uint256'
},
'children': [
{
'attributes': {
'name': 'uint'
},
'id': 34,
'name': 'ElementaryTypeName',
'src': '285:4:0'
}
],
'id': 35,
'name': 'VariableDeclaration',
'src': '285:4:0'
}
],
'name': 'ParameterList'
},
{
'children': [],
'name': 'Block'
}
],
'name': 'FunctionDefinition'
}
t.ok(common.getFullQuallyfiedFuncDefinitionIdent(contract, funDef, ['uint256', 'bool']) === 'baz.getY(uint256,bool)', 'creates right signature')
t.throws(() => common.getFullQuallyfiedFuncDefinitionIdent(contract, { name: 'MemberAccess' }, ['uint256', 'bool']), undefined, 'throws on wrong nodes') t.throws(() => common.getFullQuallyfiedFuncDefinitionIdent(contract, { name: 'MemberAccess' }, ['uint256', 'bool']), undefined, 'throws on wrong nodes')
t.throws(() => common.getFullQuallyfiedFuncDefinitionIdent({ name: 'FunctionCall' }, funDef, ['uint256', 'bool']), undefined, 'throws on wrong nodes') t.throws(() => common.getFullQuallyfiedFuncDefinitionIdent({ name: 'FunctionCall' }, fullyQualifiedFunctionDefinition, ['uint256', 'bool']), undefined, 'throws on wrong nodes')
}) })
test('staticAnalysisCommon.getLoopBlockStartIndex', function (t) { test('staticAnalysisCommon.getLoopBlockStartIndex', function (t) {
t.plan(3) t.plan(3)
var node1 = { t.equal(common.getLoopBlockStartIndex(forLoopNode), 3) // 'for' loop
'children': t.equal(common.getLoopBlockStartIndex(doWhileLoopNode), 1) // 'do-while' loop
[ t.equal(common.getLoopBlockStartIndex(whileLoopNode), 1) // 'while' loop
{
'attributes':
{
'assignments':
[
21
]
},
'children':
[
{
'attributes':
{
'constant': false,
'name': 'i',
'scope': 39,
'stateVariable': false,
'storageLocation': 'default',
'type': 'uint256',
'value': null,
'visibility': 'internal'
},
'children':
[
{
'attributes':
{
'name': 'uint',
'type': 'uint256'
},
'id': 20,
'name': 'ElementaryTypeName',
'src': '207:4:0'
}
],
'id': 21,
'name': 'VariableDeclaration',
'src': '207:6:0'
},
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 17,
'type': 'uint256',
'value': 'index'
},
'id': 22,
'name': 'Identifier',
'src': '216:5:0'
}
],
'id': 23,
'name': 'VariableDeclarationStatement',
'src': '207:14:0'
},
{
'attributes':
{
'argumentTypes': null,
'commonType':
{
'typeIdentifier': 't_uint256',
'typeString': 'uint256'
},
'isConstant': false,
'isLValue': false,
'isPure': false,
'lValueRequested': false,
'operator': '<',
'type': 'bool'
},
'children':
[
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 21,
'type': 'uint256',
'value': 'i'
},
'id': 24,
'name': 'Identifier',
'src': '223:1:0'
},
{
'attributes':
{
'argumentTypes': null,
'hexvalue': '3130',
'isConstant': false,
'isLValue': false,
'isPure': true,
'lValueRequested': false,
'subdenomination': null,
'token': 'number',
'type': 'int_const 10',
'value': '10'
},
'id': 25,
'name': 'Literal',
'src': '227:2:0'
}
],
'id': 26,
'name': 'BinaryOperation',
'src': '223:6:0'
},
{
'children':
[
{
'attributes':
{
'argumentTypes': null,
'isConstant': false,
'isLValue': false,
'isPure': false,
'lValueRequested': false,
'operator': '++',
'prefix': false,
'type': 'uint256'
},
'children':
[
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 21,
'type': 'uint256',
'value': 'i'
},
'id': 27,
'name': 'Identifier',
'src': '231:1:0'
}
],
'id': 28,
'name': 'UnaryOperation',
'src': '231:3:0'
}
],
'id': 29,
'name': 'ExpressionStatement',
'src': '231:3:0'
},
{
'children':
[
{
'children':
[
{
'attributes':
{
'argumentTypes': null,
'isConstant': false,
'isLValue': false,
'isPure': false,
'isStructConstructorCall': false,
'lValueRequested': false,
'names':
[
null
],
'type': 'uint256',
'type_conversion': false
},
'children':
[
{
'attributes':
{
'argumentTypes':
[
{
'typeIdentifier': 't_uint256',
'typeString': 'uint256'
}
],
'isConstant': false,
'isLValue': false,
'isPure': false,
'lValueRequested': false,
'member_name': 'push',
'referencedDeclaration': null,
'type': 'function (uint256) returns (uint256)'
},
'children':
[
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 4,
'type': 'uint256[] storage ref',
'value': 'array'
},
'id': 30,
'name': 'Identifier',
'src': '250:5:0'
}
],
'id': 32,
'name': 'MemberAccess',
'src': '250:10:0'
},
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 21,
'type': 'uint256',
'value': 'i'
},
'id': 33,
'name': 'Identifier',
'src': '261:1:0'
}
],
'id': 34,
'name': 'FunctionCall',
'src': '250:13:0'
}
],
'id': 35,
'name': 'ExpressionStatement',
'src': '250:13:0'
}
],
'id': 36,
'name': 'Block',
'src': '236:38:0'
}
],
'id': 37,
'name': 'ForStatement',
'src': '202:72:0'
}
var node2 = {
'children':
[
{
'attributes':
{
'argumentTypes': null,
'commonType':
{
'typeIdentifier': 't_uint256',
'typeString': 'uint256'
},
'isConstant': false,
'isLValue': false,
'isPure': false,
'lValueRequested': false,
'operator': '<',
'type': 'bool'
},
'children':
[
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 69,
'type': 'uint256',
'value': 'i'
},
'id': 82,
'name': 'Identifier',
'src': '592:1:0'
},
{
'attributes':
{
'argumentTypes': null,
'hexvalue': '3130',
'isConstant': false,
'isLValue': false,
'isPure': true,
'lValueRequested': false,
'subdenomination': null,
'token': 'number',
'type': 'int_const 10',
'value': '10'
},
'id': 83,
'name': 'Literal',
'src': '596:2:0'
}
],
'id': 84,
'name': 'BinaryOperation',
'src': '592:6:0'
},
{
'children':
[
{
'children':
[
{
'attributes':
{
'argumentTypes': null,
'isConstant': false,
'isLValue': false,
'isPure': false,
'isStructConstructorCall': false,
'lValueRequested': false,
'names':
[
null
],
'type': 'uint256',
'type_conversion': false
},
'children':
[
{
'attributes':
{
'argumentTypes':
[
{
'typeIdentifier': 't_uint256',
'typeString': 'uint256'
}
],
'isConstant': false,
'isLValue': false,
'isPure': false,
'lValueRequested': false,
'member_name': 'push',
'referencedDeclaration': null,
'type': 'function (uint256) returns (uint256)'
},
'children':
[
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 4,
'type': 'uint256[] storage ref',
'value': 'array'
},
'id': 72,
'name': 'Identifier',
'src': '544:5:0'
}
],
'id': 74,
'name': 'MemberAccess',
'src': '544:10:0'
},
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 69,
'type': 'uint256',
'value': 'i'
},
'id': 75,
'name': 'Identifier',
'src': '555:1:0'
}
],
'id': 76,
'name': 'FunctionCall',
'src': '544:13:0'
}
],
'id': 77,
'name': 'ExpressionStatement',
'src': '544:13:0'
},
{
'children':
[
{
'attributes':
{
'argumentTypes': null,
'isConstant': false,
'isLValue': false,
'isPure': false,
'lValueRequested': false,
'operator': '++',
'prefix': false,
'type': 'uint256'
},
'children':
[
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 69,
'type': 'uint256',
'value': 'i'
},
'id': 78,
'name': 'Identifier',
'src': '571:1:0'
}
],
'id': 79,
'name': 'UnaryOperation',
'src': '571:3:0'
}
],
'id': 80,
'name': 'ExpressionStatement',
'src': '571:3:0'
}
],
'id': 81,
'name': 'Block',
'src': '530:55:0'
}
],
'id': 85,
'name': 'DoWhileStatement',
'src': '528:72:0'
}
var node3 = {
'children':
[
{
'attributes':
{
'argumentTypes': null,
'commonType':
{
'typeIdentifier': 't_uint256',
'typeString': 'uint256'
},
'isConstant': false,
'isLValue': false,
'isPure': false,
'lValueRequested': false,
'operator': '<',
'type': 'bool'
},
'children':
[
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 45,
'type': 'uint256',
'value': 'i'
},
'id': 48,
'name': 'Identifier',
'src': '372:1:0'
},
{
'attributes':
{
'argumentTypes': null,
'hexvalue': '3130',
'isConstant': false,
'isLValue': false,
'isPure': true,
'lValueRequested': false,
'subdenomination': null,
'token': 'number',
'type': 'int_const 10',
'value': '10'
},
'id': 49,
'name': 'Literal',
'src': '376:2:0'
}
],
'id': 50,
'name': 'BinaryOperation',
'src': '372:6:0'
},
{
'children':
[
{
'children':
[
{
'attributes':
{
'argumentTypes': null,
'isConstant': false,
'isLValue': false,
'isPure': false,
'isStructConstructorCall': false,
'lValueRequested': false,
'names':
[
null
],
'type': 'uint256',
'type_conversion': false
},
'children':
[
{
'attributes':
{
'argumentTypes':
[
{
'typeIdentifier': 't_uint256',
'typeString': 'uint256'
}
],
'isConstant': false,
'isLValue': false,
'isPure': false,
'lValueRequested': false,
'member_name': 'push',
'referencedDeclaration': null,
'type': 'function (uint256) returns (uint256)'
},
'children':
[
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 4,
'type': 'uint256[] storage ref',
'value': 'array'
},
'id': 51,
'name': 'Identifier',
'src': '394:5:0'
}
],
'id': 53,
'name': 'MemberAccess',
'src': '394:10:0'
},
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 45,
'type': 'uint256',
'value': 'i'
},
'id': 54,
'name': 'Identifier',
'src': '405:1:0'
}
],
'id': 55,
'name': 'FunctionCall',
'src': '394:13:0'
}
],
'id': 56,
'name': 'ExpressionStatement',
'src': '394:13:0'
},
{
'children':
[
{
'attributes':
{
'argumentTypes': null,
'isConstant': false,
'isLValue': false,
'isPure': false,
'lValueRequested': false,
'operator': '++',
'prefix': false,
'type': 'uint256'
},
'children':
[
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 45,
'type': 'uint256',
'value': 'i'
},
'id': 57,
'name': 'Identifier',
'src': '421:1:0'
}
],
'id': 58,
'name': 'UnaryOperation',
'src': '421:3:0'
}
],
'id': 59,
'name': 'ExpressionStatement',
'src': '421:3:0'
}
],
'id': 60,
'name': 'Block',
'src': '380:55:0'
}
],
'id': 61,
'name': 'WhileStatement',
'src': '365:70:0'
}
t.equal(common.getLoopBlockStartIndex(node1), 3) // 'for' loop
t.equal(common.getLoopBlockStartIndex(node2), 1) // 'do-while' loop
t.equal(common.getLoopBlockStartIndex(node3), 1) // 'while' loop
}) })
// #################### Trivial Node Identification // #################### Trivial Node Identification
...@@ -1891,954 +396,38 @@ test('staticAnalysisCommon.isInlineAssembly', function (t) { ...@@ -1891,954 +396,38 @@ test('staticAnalysisCommon.isInlineAssembly', function (t) {
test('staticAnalysisCommon.isLoop', function (t) { test('staticAnalysisCommon.isLoop', function (t) {
t.plan(3) t.plan(3)
var node1 = { t.equal(common.isLoop(forLoopNode), true)
'children': t.equal(common.isLoop(doWhileLoopNode), true)
[ t.equal(common.isLoop(whileLoopNode), true)
{
'attributes':
{
'assignments':
[
21
]
},
'children':
[
{
'attributes':
{
'constant': false,
'name': 'i',
'scope': 39,
'stateVariable': false,
'storageLocation': 'default',
'type': 'uint256',
'value': null,
'visibility': 'internal'
},
'children':
[
{
'attributes':
{
'name': 'uint',
'type': 'uint256'
},
'id': 20,
'name': 'ElementaryTypeName',
'src': '207:4:0'
}
],
'id': 21,
'name': 'VariableDeclaration',
'src': '207:6:0'
},
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 17,
'type': 'uint256',
'value': 'index'
},
'id': 22,
'name': 'Identifier',
'src': '216:5:0'
}
],
'id': 23,
'name': 'VariableDeclarationStatement',
'src': '207:14:0'
},
{
'attributes':
{
'argumentTypes': null,
'commonType':
{
'typeIdentifier': 't_uint256',
'typeString': 'uint256'
},
'isConstant': false,
'isLValue': false,
'isPure': false,
'lValueRequested': false,
'operator': '<',
'type': 'bool'
},
'children':
[
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 21,
'type': 'uint256',
'value': 'i'
},
'id': 24,
'name': 'Identifier',
'src': '223:1:0'
},
{
'attributes':
{
'argumentTypes': null,
'hexvalue': '3130',
'isConstant': false,
'isLValue': false,
'isPure': true,
'lValueRequested': false,
'subdenomination': null,
'token': 'number',
'type': 'int_const 10',
'value': '10'
},
'id': 25,
'name': 'Literal',
'src': '227:2:0'
}
],
'id': 26,
'name': 'BinaryOperation',
'src': '223:6:0'
},
{
'children':
[
{
'attributes':
{
'argumentTypes': null,
'isConstant': false,
'isLValue': false,
'isPure': false,
'lValueRequested': false,
'operator': '++',
'prefix': false,
'type': 'uint256'
},
'children':
[
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 21,
'type': 'uint256',
'value': 'i'
},
'id': 27,
'name': 'Identifier',
'src': '231:1:0'
}
],
'id': 28,
'name': 'UnaryOperation',
'src': '231:3:0'
}
],
'id': 29,
'name': 'ExpressionStatement',
'src': '231:3:0'
},
{
'children':
[
{
'children':
[
{
'attributes':
{
'argumentTypes': null,
'isConstant': false,
'isLValue': false,
'isPure': false,
'isStructConstructorCall': false,
'lValueRequested': false,
'names':
[
null
],
'type': 'uint256',
'type_conversion': false
},
'children':
[
{
'attributes':
{
'argumentTypes':
[
{
'typeIdentifier': 't_uint256',
'typeString': 'uint256'
}
],
'isConstant': false,
'isLValue': false,
'isPure': false,
'lValueRequested': false,
'member_name': 'push',
'referencedDeclaration': null,
'type': 'function (uint256) returns (uint256)'
},
'children':
[
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 4,
'type': 'uint256[] storage ref',
'value': 'array'
},
'id': 30,
'name': 'Identifier',
'src': '250:5:0'
}
],
'id': 32,
'name': 'MemberAccess',
'src': '250:10:0'
},
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 21,
'type': 'uint256',
'value': 'i'
},
'id': 33,
'name': 'Identifier',
'src': '261:1:0'
}
],
'id': 34,
'name': 'FunctionCall',
'src': '250:13:0'
}
],
'id': 35,
'name': 'ExpressionStatement',
'src': '250:13:0'
}
],
'id': 36,
'name': 'Block',
'src': '236:38:0'
}
],
'id': 37,
'name': 'ForStatement',
'src': '202:72:0'
}
var node2 = {
'children':
[
{
'attributes':
{
'argumentTypes': null,
'commonType':
{
'typeIdentifier': 't_uint256',
'typeString': 'uint256'
},
'isConstant': false,
'isLValue': false,
'isPure': false,
'lValueRequested': false,
'operator': '<',
'type': 'bool'
},
'children':
[
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 69,
'type': 'uint256',
'value': 'i'
},
'id': 82,
'name': 'Identifier',
'src': '592:1:0'
},
{
'attributes':
{
'argumentTypes': null,
'hexvalue': '3130',
'isConstant': false,
'isLValue': false,
'isPure': true,
'lValueRequested': false,
'subdenomination': null,
'token': 'number',
'type': 'int_const 10',
'value': '10'
},
'id': 83,
'name': 'Literal',
'src': '596:2:0'
}
],
'id': 84,
'name': 'BinaryOperation',
'src': '592:6:0'
},
{
'children':
[
{
'children':
[
{
'attributes':
{
'argumentTypes': null,
'isConstant': false,
'isLValue': false,
'isPure': false,
'isStructConstructorCall': false,
'lValueRequested': false,
'names':
[
null
],
'type': 'uint256',
'type_conversion': false
},
'children':
[
{
'attributes':
{
'argumentTypes':
[
{
'typeIdentifier': 't_uint256',
'typeString': 'uint256'
}
],
'isConstant': false,
'isLValue': false,
'isPure': false,
'lValueRequested': false,
'member_name': 'push',
'referencedDeclaration': null,
'type': 'function (uint256) returns (uint256)'
},
'children':
[
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 4,
'type': 'uint256[] storage ref',
'value': 'array'
},
'id': 72,
'name': 'Identifier',
'src': '544:5:0'
}
],
'id': 74,
'name': 'MemberAccess',
'src': '544:10:0'
},
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 69,
'type': 'uint256',
'value': 'i'
},
'id': 75,
'name': 'Identifier',
'src': '555:1:0'
}
],
'id': 76,
'name': 'FunctionCall',
'src': '544:13:0'
}
],
'id': 77,
'name': 'ExpressionStatement',
'src': '544:13:0'
},
{
'children':
[
{
'attributes':
{
'argumentTypes': null,
'isConstant': false,
'isLValue': false,
'isPure': false,
'lValueRequested': false,
'operator': '++',
'prefix': false,
'type': 'uint256'
},
'children':
[
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 69,
'type': 'uint256',
'value': 'i'
},
'id': 78,
'name': 'Identifier',
'src': '571:1:0'
}
],
'id': 79,
'name': 'UnaryOperation',
'src': '571:3:0'
}
],
'id': 80,
'name': 'ExpressionStatement',
'src': '571:3:0'
}
],
'id': 81,
'name': 'Block',
'src': '530:55:0'
}
],
'id': 85,
'name': 'DoWhileStatement',
'src': '528:72:0'
}
var node3 = {
'children':
[
{
'attributes':
{
'argumentTypes': null,
'commonType':
{
'typeIdentifier': 't_uint256',
'typeString': 'uint256'
},
'isConstant': false,
'isLValue': false,
'isPure': false,
'lValueRequested': false,
'operator': '<',
'type': 'bool'
},
'children':
[
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 45,
'type': 'uint256',
'value': 'i'
},
'id': 48,
'name': 'Identifier',
'src': '372:1:0'
},
{
'attributes':
{
'argumentTypes': null,
'hexvalue': '3130',
'isConstant': false,
'isLValue': false,
'isPure': true,
'lValueRequested': false,
'subdenomination': null,
'token': 'number',
'type': 'int_const 10',
'value': '10'
},
'id': 49,
'name': 'Literal',
'src': '376:2:0'
}
],
'id': 50,
'name': 'BinaryOperation',
'src': '372:6:0'
},
{
'children':
[
{
'children':
[
{
'attributes':
{
'argumentTypes': null,
'isConstant': false,
'isLValue': false,
'isPure': false,
'isStructConstructorCall': false,
'lValueRequested': false,
'names':
[
null
],
'type': 'uint256',
'type_conversion': false
},
'children':
[
{
'attributes':
{
'argumentTypes':
[
{
'typeIdentifier': 't_uint256',
'typeString': 'uint256'
}
],
'isConstant': false,
'isLValue': false,
'isPure': false,
'lValueRequested': false,
'member_name': 'push',
'referencedDeclaration': null,
'type': 'function (uint256) returns (uint256)'
},
'children':
[
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 4,
'type': 'uint256[] storage ref',
'value': 'array'
},
'id': 51,
'name': 'Identifier',
'src': '394:5:0'
}
],
'id': 53,
'name': 'MemberAccess',
'src': '394:10:0'
},
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 45,
'type': 'uint256',
'value': 'i'
},
'id': 54,
'name': 'Identifier',
'src': '405:1:0'
}
],
'id': 55,
'name': 'FunctionCall',
'src': '394:13:0'
}
],
'id': 56,
'name': 'ExpressionStatement',
'src': '394:13:0'
},
{
'children':
[
{
'attributes':
{
'argumentTypes': null,
'isConstant': false,
'isLValue': false,
'isPure': false,
'lValueRequested': false,
'operator': '++',
'prefix': false,
'type': 'uint256'
},
'children':
[
{
'attributes':
{
'argumentTypes': null,
'overloadedDeclarations':
[
null
],
'referencedDeclaration': 45,
'type': 'uint256',
'value': 'i'
},
'id': 57,
'name': 'Identifier',
'src': '421:1:0'
}
],
'id': 58,
'name': 'UnaryOperation',
'src': '421:3:0'
}
],
'id': 59,
'name': 'ExpressionStatement',
'src': '421:3:0'
}
],
'id': 60,
'name': 'Block',
'src': '380:55:0'
}
],
'id': 61,
'name': 'WhileStatement',
'src': '365:70:0'
}
t.equal(common.isLoop(node1), true)
t.equal(common.isLoop(node2), true)
t.equal(common.isLoop(node3), true)
}) })
// #################### Complex Node Identification // #################### Complex Node Identification
test('staticAnalysisCommon.isBuiltinFunctionCall', function (t) { test('staticAnalysisCommon.isBuiltinFunctionCall', function (t) {
t.plan(2) t.plan(2)
var selfdestruct = {
'attributes': {
'type': 'tuple()',
'type_conversion': false
},
'children': [
{
'attributes': {
'type': 'function (address)',
'value': 'selfdestruct'
},
'name': 'Identifier'
},
{
'attributes': {
'type': 'address',
'value': 'a'
},
'name': 'Identifier'
}
],
'name': 'FunctionCall'
}
var localCall = {
'attributes': {
'type': 'tuple()',
'type_conversion': false
},
'children': [
{
'attributes': {
'type': 'function (struct Ballot.Voter storage pointer)',
'value': 'bli'
},
'name': 'Identifier'
},
{
'attributes': {
'type': 'struct Ballot.Voter storage pointer',
'value': 'x'
},
'name': 'Identifier'
}
],
'name': 'FunctionCall'
}
t.ok(common.isBuiltinFunctionCall(selfdestruct), 'selfdestruct is builtin') t.ok(common.isBuiltinFunctionCall(selfdestruct), 'selfdestruct is builtin')
t.notOk(common.isBuiltinFunctionCall(localCall), 'local call is not builtin') t.notOk(common.isBuiltinFunctionCall(localCall), 'local call is not builtin')
}) })
test('staticAnalysisCommon.isStorageVariableDeclaration', function (t) { test('staticAnalysisCommon.isStorageVariableDeclaration', function (t) {
t.plan(3) t.plan(3)
var node1 = { t.ok(common.isStorageVariableDeclaration(storageVariableNodes.node1), 'struct storage pointer param is storage')
'attributes': { t.ok(common.isStorageVariableDeclaration(storageVariableNodes.node2), 'struct storage pointer mapping param is storage')
'name': 'x', t.notOk(common.isStorageVariableDeclaration(storageVariableNodes.node3), 'bytes is not storage')
'type': 'struct Ballot.Voter storage pointer'
},
'children': [
{
'attributes': {
'name': 'Voter'
},
'id': 43,
'name': 'UserDefinedTypeName',
'src': '604:5:0'
}
],
'id': 44,
'name': 'VariableDeclaration',
'src': '604:15:0'
}
var node2 = {
'attributes': {
'name': 'voters',
'type': 'mapping(address => struct Ballot.Voter storage ref)'
},
'children': [
{
'children': [
{
'attributes': {
'name': 'address'
},
'id': 16,
'name': 'ElementaryTypeName',
'src': '235:7:0'
},
{
'attributes': {
'name': 'Voter'
},
'id': 17,
'name': 'UserDefinedTypeName',
'src': '246:5:0'
}
],
'id': 18,
'name': 'Mapping',
'src': '227:25:0'
}
],
'id': 19,
'name': 'VariableDeclaration',
'src': '227:32:0'
}
var node3 = {
'attributes': {
'name': 'voters',
'type': 'bytes32'
},
'children': [
{
'attributes': {
'name': 'bytes'
},
'id': 16,
'name': 'ElementaryTypeName',
'src': '235:7:0'
}
],
'id': 19,
'name': 'VariableDeclaration',
'src': '227:32:0'
}
t.ok(common.isStorageVariableDeclaration(node1), 'struct storage pointer param is storage')
t.ok(common.isStorageVariableDeclaration(node2), 'struct storage pointer mapping param is storage')
t.notOk(common.isStorageVariableDeclaration(node3), 'bytes is not storage')
}) })
test('staticAnalysisCommon.isInteraction', function (t) { test('staticAnalysisCommon.isInteraction', function (t) {
t.plan(6) t.plan(6)
var sendAst = { name: 'MemberAccess', children: [{attributes: { value: 'd', type: 'address' }}], attributes: { value: 'send', type: 'function (uint256) returns (bool)' } } t.ok(common.isInteraction(lowlevelCall.sendAst), 'send is interaction')
var callAst = { name: 'MemberAccess', children: [{attributes: { value: 'f', type: 'address' }}], attributes: { member_name: 'call', type: 'function () payable returns (bool)' } } t.ok(common.isInteraction(lowlevelCall.callAst), 'call is interaction')
var callcodeAst = { name: 'MemberAccess', children: [{attributes: { value: 'f', type: 'address' }}], attributes: { member_name: 'callcode', type: 'function () payable returns (bool)' } } t.ok(common.isInteraction(externalDirect), 'ExternalDirecCall is interaction')
var delegatecallAst = { name: 'MemberAccess', children: [{attributes: { value: 'g', type: 'address' }}], attributes: { member_name: 'delegatecall', type: 'function () returns (bool)' } } t.notOk(common.isInteraction(lowlevelCall.callcodeAst), 'callcode is not interaction')
var nodeExtDir = { t.notOk(common.isInteraction(lowlevelCall.delegatecallAst), 'callcode is not interaction')
attributes: { t.notOk(common.isInteraction(localCall), 'local call is not interaction')
member_name: 'info',
type: 'function () payable external returns (uint256)'
},
children: [
{
attributes: {
type: 'contract InfoFeed',
value: 'f'
},
id: 30,
name: 'Identifier',
src: '405:1:0'
}
],
id: 32,
name: 'MemberAccess',
src: '405:6:0'
}
var nodeNot = {
'attributes': {
'type': 'tuple()',
'type_conversion': false
},
'children': [
{
'attributes': {
'type': 'function (struct Ballot.Voter storage pointer)',
'value': 'bli'
},
'id': 37,
'name': 'Identifier',
'src': '540:3:0'
},
{
'attributes': {
'type': 'struct Ballot.Voter storage pointer',
'value': 'x'
},
'id': 38,
'name': 'Identifier',
'src': '544:1:0'
}
],
'id': 39,
'name': 'FunctionCall',
'src': '540:6:0'
}
t.ok(common.isInteraction(sendAst), 'send is interaction')
t.ok(common.isInteraction(callAst), 'call is interaction')
t.ok(common.isInteraction(nodeExtDir), 'ExternalDirecCall is interaction')
t.notOk(common.isInteraction(callcodeAst), 'callcode is not interaction')
t.notOk(common.isInteraction(delegatecallAst), 'callcode is not interaction')
t.notOk(common.isInteraction(nodeNot), 'local call is not interaction')
}) })
test('staticAnalysisCommon.isEffect', function (t) { test('staticAnalysisCommon.isEffect', function (t) {
t.plan(5) t.plan(5)
var inlineAssembly = {
'children': [
],
'id': 21,
'name': 'InlineAssembly',
'src': '809:41:0'
}
var assignment = {
'attributes': {
'operator': '=',
'type': 'uint256'
},
'children': [
{
'attributes': {
'type': 'uint256'
},
'children': [
{
'attributes': {
'type': 'mapping(address => uint256)',
'value': 'c'
},
'id': 61,
'name': 'Identifier',
'src': '873:1:0'
},
{
'attributes': {
'member_name': 'sender',
'type': 'address'
},
'children': [
{
'attributes': {
'type': 'msg',
'value': 'msg'
},
'id': 62,
'name': 'Identifier',
'src': '875:3:0'
}
],
'id': 63,
'name': 'MemberAccess',
'src': '875:10:0'
}
],
'id': 64,
'name': 'IndexAccess',
'src': '873:13:0'
},
{
'attributes': {
'hexvalue': '30',
'subdenomination': null,
'token': null,
'type': 'int_const 0',
'value': '0'
},
'id': 65,
'name': 'Literal',
'src': '889:1:0'
}
],
'id': 66,
'name': 'Assignment',
'src': '873:17:0'
}
var unaryOp = { name: 'UnaryOperation', attributes: { operator: '++' } } var unaryOp = { name: 'UnaryOperation', attributes: { operator: '++' } }
t.ok(common.isEffect(inlineAssembly), 'inline assembly is treated as effect') t.ok(common.isEffect(inlineAssembly), 'inline assembly is treated as effect')
t.ok(common.isEffect(assignment), 'assignment is treated as effect') t.ok(common.isEffect(assignment), 'assignment is treated as effect')
...@@ -2850,120 +439,11 @@ test('staticAnalysisCommon.isEffect', function (t) { ...@@ -2850,120 +439,11 @@ test('staticAnalysisCommon.isEffect', function (t) {
test('staticAnalysisCommon.isWriteOnStateVariable', function (t) { test('staticAnalysisCommon.isWriteOnStateVariable', function (t) {
t.plan(3) t.plan(3)
var inlineAssembly = { let node1 = JSON.parse(JSON.stringify(storageVariableNodes.node1))
'children': [ let node2 = node1
], let node3 = node1
'id': 21, node2.attributes.name = 'y'
'name': 'InlineAssembly', node3.attributes.name = 'xx'
'src': '809:41:0'
}
var assignment = {
'attributes': {
'operator': '=',
'type': 'uint256'
},
'children': [
{
'attributes': {
'type': 'uint256'
},
'children': [
{
'attributes': {
'type': 'mapping(address => uint256)',
'value': 'c'
},
'id': 61,
'name': 'Identifier',
'src': '873:1:0'
},
{
'attributes': {
'member_name': 'sender',
'type': 'address'
},
'children': [
{
'attributes': {
'type': 'msg',
'value': 'msg'
},
'id': 62,
'name': 'Identifier',
'src': '875:3:0'
}
],
'id': 63,
'name': 'MemberAccess',
'src': '875:10:0'
}
],
'id': 64,
'name': 'IndexAccess',
'src': '873:13:0'
},
{
'attributes': {
'hexvalue': '30',
'subdenomination': null,
'token': null,
'type': 'int_const 0',
'value': '0'
},
'id': 65,
'name': 'Literal',
'src': '889:1:0'
}
],
'id': 66,
'name': 'Assignment',
'src': '873:17:0'
}
var node1 = {
'attributes': {
'name': 'x',
'type': 'struct Ballot.Voter storage pointer'
},
'children': [
{
'attributes': {
'name': 'Voter'
},
'name': 'UserDefinedTypeName'
}
],
'name': 'VariableDeclaration'
}
var node2 = {
'attributes': {
'name': 'y',
'type': 'uint'
},
'children': [
{
'attributes': {
'name': 'Voter'
},
'name': 'UserDefinedTypeName'
}
],
'name': 'VariableDeclaration'
}
var node3 = {
'attributes': {
'name': 'xx',
'type': 'uint'
},
'children': [
{
'attributes': {
'name': 'Voter'
},
'name': 'UserDefinedTypeName'
}
],
'name': 'VariableDeclaration'
}
t.ok(common.isWriteOnStateVariable(inlineAssembly, [node1, node2, node3]), 'inline Assembly is write on state') t.ok(common.isWriteOnStateVariable(inlineAssembly, [node1, node2, node3]), 'inline Assembly is write on state')
t.notOk(common.isWriteOnStateVariable(assignment, [node1, node2, node3]), 'assignment on non state is not write on state') t.notOk(common.isWriteOnStateVariable(assignment, [node1, node2, node3]), 'assignment on non state is not write on state')
node3.attributes.name = 'c' node3.attributes.name = 'c'
...@@ -2972,55 +452,9 @@ test('staticAnalysisCommon.isWriteOnStateVariable', function (t) { ...@@ -2972,55 +452,9 @@ test('staticAnalysisCommon.isWriteOnStateVariable', function (t) {
test('staticAnalysisCommon.isStateVariable', function (t) { test('staticAnalysisCommon.isStateVariable', function (t) {
t.plan(3) t.plan(3)
var node1 = { t.ok(common.isStateVariable('x', [storageVariableNodes.node1, storageVariableNodes.node2]), 'is contained')
'attributes': { t.ok(common.isStateVariable('x', [storageVariableNodes.node2, storageVariableNodes.node1, storageVariableNodes.node1]), 'is contained twice')
'name': 'x', t.notOk(common.isStateVariable('x', [storageVariableNodes.node2, storageVariableNodes.node3]), 'not contained')
'type': 'struct Ballot.Voter storage pointer'
},
'children': [
{
'attributes': {
'name': 'Voter'
},
'name': 'UserDefinedTypeName'
}
],
'name': 'VariableDeclaration'
}
var node2 = {
'attributes': {
'name': 'y',
'type': 'uint'
},
'children': [
{
'attributes': {
'name': 'Voter'
},
'name': 'UserDefinedTypeName'
}
],
'name': 'VariableDeclaration'
}
var node3 = {
'attributes': {
'name': 'xx',
'type': 'uint'
},
'children': [
{
'attributes': {
'name': 'Voter'
},
'name': 'UserDefinedTypeName'
}
],
'name': 'VariableDeclaration'
}
t.ok(common.isStateVariable('x', [node1, node2]), 'is contained')
t.ok(common.isStateVariable('x', [node2, node1, node1]), 'is contained twice')
t.notOk(common.isStateVariable('x', [node2, node3]), 'not contained')
}) })
test('staticAnalysisCommon.isConstantFunction', function (t) { test('staticAnalysisCommon.isConstantFunction', function (t) {
...@@ -3069,63 +503,18 @@ test('staticAnalysisCommon.isFullyImplementedContract', function (t) { ...@@ -3069,63 +503,18 @@ test('staticAnalysisCommon.isFullyImplementedContract', function (t) {
test('staticAnalysisCommon.isCallToNonConstLocalFunction', function (t) { test('staticAnalysisCommon.isCallToNonConstLocalFunction', function (t) {
t.plan(2) t.plan(2)
var node1 = { t.ok(common.isCallToNonConstLocalFunction(localCall), 'should be call to non const Local func')
'attributes': { localCall.children[0].attributes.type = 'function (struct Ballot.Voter storage pointer) constant payable (uint256)'
'type': 'tuple()', t.notok(common.isCallToNonConstLocalFunction(localCall), 'should no longer be call to non const Local func')
'type_conversion': false
},
'children': [
{
'attributes': {
'type': 'function (struct Ballot.Voter storage pointer)',
'value': 'bli'
},
'name': 'Identifier'
},
{
'attributes': {
'type': 'struct Ballot.Voter storage pointer',
'value': 'x'
},
'name': 'Identifier'
}
],
'name': 'FunctionCall'
}
t.ok(common.isCallToNonConstLocalFunction(node1), 'should be call to non const Local func')
node1.children[0].attributes.type = 'function (struct Ballot.Voter storage pointer) constant payable (uint256)'
t.notok(common.isCallToNonConstLocalFunction(node1), 'should no longer be call to non const Local func')
}) })
test('staticAnalysisCommon.isExternalDirectCall', function (t) { test('staticAnalysisCommon.isExternalDirectCall', function (t) {
t.plan(5) t.plan(5)
var node = {
attributes: {
member_name: 'info',
type: 'function () payable external returns (uint256)'
},
children: [
{
attributes: {
type: 'contract InfoFeed',
value: 'f'
},
id: 30,
name: 'Identifier',
src: '405:1:0'
}
],
id: 32,
name: 'MemberAccess',
src: '405:6:0'
}
var node2 = { name: 'MemberAccess', children: [{attributes: { value: 'this', type: 'contract test' }}], attributes: { value: 'b', type: 'function (bytes32,address) returns (bool)' } } var node2 = { name: 'MemberAccess', children: [{attributes: { value: 'this', type: 'contract test' }}], attributes: { value: 'b', type: 'function (bytes32,address) returns (bool)' } }
t.notOk(common.isThisLocalCall(node), 'is this.local_method() used should not work') t.notOk(common.isThisLocalCall(externalDirect), 'is this.local_method() used should not work')
t.notOk(common.isBlockTimestampAccess(node), 'is block.timestamp used should not work') t.notOk(common.isBlockTimestampAccess(externalDirect), 'is block.timestamp used should not work')
t.notOk(common.isNowAccess(node), 'is now used should not work') t.notOk(common.isNowAccess(externalDirect), 'is now used should not work')
t.ok(common.isExternalDirectCall(node), 'f.info() should be external direct call') t.ok(common.isExternalDirectCall(externalDirect), 'f.info() should be external direct call')
t.notOk(common.isExternalDirectCall(node2), 'local call is not an exernal call') t.notOk(common.isExternalDirectCall(node2), 'local call is not an exernal call')
}) })
...@@ -3147,320 +536,71 @@ test('staticAnalysisCommon.isBlockTimestampAccess', function (t) { ...@@ -3147,320 +536,71 @@ test('staticAnalysisCommon.isBlockTimestampAccess', function (t) {
test('staticAnalysisCommon.isBlockBlockhashAccess', function (t) { test('staticAnalysisCommon.isBlockBlockhashAccess', function (t) {
t.plan(4) t.plan(4)
var node = { t.notOk(common.isThisLocalCall(blockHashAccess), 'is this.local_method() used should not work')
'attributes': { t.notOk(common.isBlockTimestampAccess(blockHashAccess), 'is block.timestamp used should not work')
'member_name': 'blockhash', t.ok(common.isBlockBlockHashAccess(blockHashAccess), 'blockhash should work') // todo:
'type': 'function (uint256) returns (bytes32)' t.notOk(common.isNowAccess(blockHashAccess), 'is now used should not work')
},
'children': [
{
'attributes': {
'type': 'block',
'value': 'block'
},
'name': 'Identifier'
}
],
'name': 'MemberAccess'
}
t.notOk(common.isThisLocalCall(node), 'is this.local_method() used should not work')
t.notOk(common.isBlockTimestampAccess(node), 'is block.timestamp used should not work')
t.ok(common.isBlockBlockHashAccess(node), 'blockhash should work') // todo:
t.notOk(common.isNowAccess(node), 'is now used should not work')
}) })
test('staticAnalysisCommon.isThisLocalCall', function (t) { test('staticAnalysisCommon.isThisLocalCall', function (t) {
t.plan(3) t.plan(3)
var node = { name: 'MemberAccess', children: [{attributes: { value: 'this', type: 'contract test' }}], attributes: { value: 'b', type: 'function (bytes32,address) returns (bool)' } } t.ok(common.isThisLocalCall(thisLocalCall), 'is this.local_method() used should work')
t.ok(common.isThisLocalCall(node), 'is this.local_method() used should work') t.notOk(common.isBlockTimestampAccess(thisLocalCall), 'is block.timestamp used should not work')
t.notOk(common.isBlockTimestampAccess(node), 'is block.timestamp used should not work') t.notOk(common.isNowAccess(thisLocalCall), 'is now used should not work')
t.notOk(common.isNowAccess(node), 'is now used should not work')
}) })
test('staticAnalysisCommon.isSuperLocalCall', function (t) { test('staticAnalysisCommon.isSuperLocalCall', function (t) {
t.plan(4) t.plan(4)
var node = { t.ok(common.isSuperLocalCall(superLocal), 'is super.local_method() used should work')
'attributes': { t.notOk(common.isThisLocalCall(superLocal), 'is this.local_method() used should not work')
'member_name': 'duper', t.notOk(common.isBlockTimestampAccess(superLocal), 'is block.timestamp used should not work')
'type': 'function ()' t.notOk(common.isNowAccess(superLocal), 'is now used should not work')
},
'children': [
{
'attributes': {
'type': 'contract super a',
'value': 'super'
},
'name': 'Identifier'
}
],
'name': 'MemberAccess'
}
t.ok(common.isSuperLocalCall(node), 'is super.local_method() used should work')
t.notOk(common.isThisLocalCall(node), 'is this.local_method() used should not work')
t.notOk(common.isBlockTimestampAccess(node), 'is block.timestamp used should not work')
t.notOk(common.isNowAccess(node), 'is now used should not work')
}) })
test('staticAnalysisCommon.isLibraryCall', function (t) { test('staticAnalysisCommon.isLibraryCall', function (t) {
t.plan(5) t.plan(5)
var node = { t.ok(common.isLibraryCall(libCall), 'is lib call should not work')
'attributes': { t.notOk(common.isSuperLocalCall(libCall), 'is super.local_method() used should not work')
'member_name': 'insert', t.notOk(common.isThisLocalCall(libCall), 'is this.local_method() used should not work')
'type': 'function (struct Set.Data storage pointer,uint256) returns (bool)' t.notOk(common.isBlockTimestampAccess(libCall), 'is block.timestamp used should not work')
}, t.notOk(common.isNowAccess(libCall), 'is now used should not work')
'children': [
{
'attributes': {
'type': 'type(library Set)',
'value': 'Set'
},
'name': 'Identifier'
}
],
'name': 'MemberAccess'
}
t.ok(common.isLibraryCall(node), 'is lib call should not work')
t.notOk(common.isSuperLocalCall(node), 'is super.local_method() used should not work')
t.notOk(common.isThisLocalCall(node), 'is this.local_method() used should not work')
t.notOk(common.isBlockTimestampAccess(node), 'is block.timestamp used should not work')
t.notOk(common.isNowAccess(node), 'is now used should not work')
}) })
test('staticAnalysisCommon.isLocalCall', function (t) { test('staticAnalysisCommon.isLocalCall', function (t) {
t.plan(5) t.plan(5)
var node1 = { t.ok(common.isLocalCall(localCall), 'isLocalCall')
'attributes': { t.notOk(common.isLowLevelCall(localCall), 'is not low level call')
'type': 'tuple()', t.notOk(common.isExternalDirectCall(localCall), 'is not external direct call')
'type_conversion': false t.notOk(common.isEffect(localCall), 'is not effect')
}, t.notOk(common.isInteraction(localCall), 'is not interaction')
'children': [
{
'attributes': {
'type': 'function (struct Ballot.Voter storage pointer)',
'value': 'bli'
},
'id': 37,
'name': 'Identifier',
'src': '540:3:0'
},
{
'attributes': {
'type': 'struct Ballot.Voter storage pointer',
'value': 'x'
},
'id': 38,
'name': 'Identifier',
'src': '544:1:0'
}
],
'id': 39,
'name': 'FunctionCall',
'src': '540:6:0'
}
t.ok(common.isLocalCall(node1), 'isLocalCall')
t.notOk(common.isLowLevelCall(node1), 'is not low level call')
t.notOk(common.isExternalDirectCall(node1), 'is not external direct call')
t.notOk(common.isEffect(node1), 'is not effect')
t.notOk(common.isInteraction(node1), 'is not interaction')
}) })
test('staticAnalysisCommon.isLowLevelCall', function (t) { test('staticAnalysisCommon.isLowLevelCall', function (t) {
t.plan(6) t.plan(6)
var sendAst = { name: 'MemberAccess', children: [{attributes: { value: 'd', type: 'address' }}], attributes: { value: 'send', type: 'function (uint256) returns (bool)' } } t.ok(common.isLowLevelSendInst(lowlevelCall.sendAst) && common.isLowLevelCall(lowlevelCall.sendAst), 'send is llc should work')
var callAst = { name: 'MemberAccess', children: [{attributes: { value: 'f', type: 'address' }}], attributes: { member_name: 'call', type: 'function () payable returns (bool)' } } t.ok(common.isLowLevelCallInst(lowlevelCall.callAst) && common.isLowLevelCall(lowlevelCall.callAst), 'call is llc should work')
var callcodeAst = { name: 'MemberAccess', children: [{attributes: { value: 'f', type: 'address' }}], attributes: { member_name: 'callcode', type: 'function () payable returns (bool)' } } t.notOk(common.isLowLevelCallInst(lowlevelCall.callcodeAst), 'callcode is not call')
var delegatecallAst = { name: 'MemberAccess', children: [{attributes: { value: 'g', type: 'address' }}], attributes: { member_name: 'delegatecall', type: 'function () returns (bool)' } } t.ok(common.isLowLevelCallcodeInst(lowlevelCall.callcodeAst) && common.isLowLevelCall(lowlevelCall.callcodeAst), 'callcode is llc should work')
t.notOk(common.isLowLevelCallcodeInst(lowlevelCall.callAst), 'call is not callcode')
t.ok(common.isLowLevelSendInst(sendAst) && common.isLowLevelCall(sendAst), 'send is llc should work') t.ok(common.isLowLevelDelegatecallInst(lowlevelCall.delegatecallAst) && common.isLowLevelCall(lowlevelCall.delegatecallAst), 'delegatecall is llc should work')
t.ok(common.isLowLevelCallInst(callAst) && common.isLowLevelCall(callAst), 'call is llc should work')
t.notOk(common.isLowLevelCallInst(callcodeAst), 'callcode is not call')
t.ok(common.isLowLevelCallcodeInst(callcodeAst) && common.isLowLevelCall(callcodeAst), 'callcode is llc should work')
t.notOk(common.isLowLevelCallcodeInst(callAst), 'call is not callcode')
t.ok(common.isLowLevelDelegatecallInst(delegatecallAst) && common.isLowLevelCall(delegatecallAst), 'delegatecall is llc should work')
}) })
test('staticAnalysisCommon: Call of parameter function', function (t) { test('staticAnalysisCommon: Call of parameter function', function (t) {
t.plan(7) t.plan(7)
var node1 = { t.ok(common.isLocalCall(parameterFunction), 'is not LocalCall')
'attributes': { t.notOk(common.isThisLocalCall(parameterFunction), 'is not this local call')
'argumentTypes': null, t.notOk(common.isSuperLocalCall(parameterFunction), 'is not super local call')
'isConstant': false, t.notOk(common.isExternalDirectCall(parameterFunction), 'is not ExternalDirectCall')
'isLValue': false, t.notOk(common.isLibraryCall(parameterFunction), 'is not LibraryCall')
'isPure': false,
'isStructConstructorCall': false, t.equals(common.getFunctionCallType(parameterFunction), 'function (uint256,uint256) pure returns (uint256)', 'Extracts right type')
'lValueRequested': false, t.equals(common.getFunctionCallTypeParameterType(parameterFunction), 'uint256,uint256', 'Extracts param right type')
'names': [
null
],
'type': 'uint256',
'type_conversion': false
},
'children': [
{
'attributes': {
'argumentTypes': [
{
'typeIdentifier': 't_uint256',
'typeString': 'uint256'
},
{
'typeIdentifier': 't_uint256',
'typeString': 'uint256'
}
],
'overloadedDeclarations': [
null
],
'referencedDeclaration': 25,
'type': 'function (uint256,uint256) pure returns (uint256)',
'value': 'f'
},
'id': 34,
'name': 'Identifier',
'src': '267:1:0'
},
{
'attributes': {
'argumentTypes': null,
'overloadedDeclarations': [
null
],
'referencedDeclaration': 27,
'type': 'uint256',
'value': 'x'
},
'id': 35,
'name': 'Identifier',
'src': '269:1:0'
},
{
'attributes': {
'argumentTypes': null,
'overloadedDeclarations': [
null
],
'referencedDeclaration': 29,
'type': 'uint256',
'value': 'y'
},
'id': 36,
'name': 'Identifier',
'src': '272:1:0'
}
],
'id': 37,
'name': 'FunctionCall',
'src': '267:7:0'
}
t.ok(common.isLocalCall(node1), 'is not LocalCall')
t.notOk(common.isThisLocalCall(node1), 'is not this local call')
t.notOk(common.isSuperLocalCall(node1), 'is not super local call')
t.notOk(common.isExternalDirectCall(node1), 'is not ExternalDirectCall')
t.notOk(common.isLibraryCall(node1), 'is not LibraryCall')
t.equals(common.getFunctionCallType(node1), 'function (uint256,uint256) pure returns (uint256)', 'Extracts right type')
t.equals(common.getFunctionCallTypeParameterType(node1), 'uint256,uint256', 'Extracts param right type')
}) })
test('staticAnalysisCommon: function call with of function with function parameter', function (t) { test('staticAnalysisCommon: function call with of function with function parameter', function (t) {
t.plan(2) t.plan(2)
var node1 = { t.equals(common.getFunctionCallType(parameterFunctionCall), 'function (function (uint256,uint256) pure returns (uint256),uint256,uint256) pure returns (uint256)', 'Extracts right type')
'attributes': { t.equals(common.getFunctionCallTypeParameterType(parameterFunctionCall), 'function (uint256,uint256) pure returns (uint256),uint256,uint256', 'Extracts param right type')
'argumentTypes': null,
'isConstant': false,
'isLValue': false,
'isPure': false,
'isStructConstructorCall': false,
'lValueRequested': false,
'names': [
null
],
'type': 'uint256',
'type_conversion': false
},
'children': [
{
'attributes': {
'argumentTypes': [
{
'typeIdentifier': 't_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$',
'typeString': 'function (uint256,uint256) pure returns (uint256)'
},
{
'typeIdentifier': 't_uint256',
'typeString': 'uint256'
},
{
'typeIdentifier': 't_uint256',
'typeString': 'uint256'
}
],
'overloadedDeclarations': [
null
],
'referencedDeclaration': 40,
'type': 'function (function (uint256,uint256) pure returns (uint256),uint256,uint256) pure returns (uint256)',
'value': 'eval'
},
'id': 49,
'name': 'Identifier',
'src': '361:4:0'
},
{
'attributes': {
'argumentTypes': null,
'overloadedDeclarations': [
null
],
'referencedDeclaration': 15,
'type': 'function (uint256,uint256) pure returns (uint256)',
'value': 'plus'
},
'id': 50,
'name': 'Identifier',
'src': '366:4:0'
},
{
'attributes': {
'argumentTypes': null,
'overloadedDeclarations': [
null
],
'referencedDeclaration': 42,
'type': 'uint256',
'value': 'x'
},
'id': 51,
'name': 'Identifier',
'src': '372:1:0'
},
{
'attributes': {
'argumentTypes': null,
'overloadedDeclarations': [
null
],
'referencedDeclaration': 44,
'type': 'uint256',
'value': 'y'
},
'id': 52,
'name': 'Identifier',
'src': '375:1:0'
}
],
'id': 53,
'name': 'FunctionCall',
'src': '361:16:0'
}
t.equals(common.getFunctionCallType(node1), 'function (function (uint256,uint256) pure returns (uint256),uint256,uint256) pure returns (uint256)', 'Extracts right type')
t.equals(common.getFunctionCallTypeParameterType(node1), 'function (uint256,uint256) pure returns (uint256),uint256,uint256', 'Extracts param right type')
}) })
test('staticAnalysisCommon: require call', function (t) { test('staticAnalysisCommon: require call', function (t) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment