diff --git a/remix-analyzer/test/analysis/astBlocks/assignment.json b/remix-analyzer/test/analysis/astBlocks/assignment.json new file mode 100644 index 0000000000..1e368adef7 --- /dev/null +++ b/remix-analyzer/test/analysis/astBlocks/assignment.json @@ -0,0 +1,62 @@ +{ + "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 diff --git a/remix-analyzer/test/analysis/astBlocks/blockHashAccess.json b/remix-analyzer/test/analysis/astBlocks/blockHashAccess.json new file mode 100644 index 0000000000..42f01ef509 --- /dev/null +++ b/remix-analyzer/test/analysis/astBlocks/blockHashAccess.json @@ -0,0 +1,16 @@ +{ + "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 diff --git a/remix-analyzer/test/analysis/astBlocks/doWhileLoopNode.json b/remix-analyzer/test/analysis/astBlocks/doWhileLoopNode.json new file mode 100644 index 0000000000..4b5d880707 --- /dev/null +++ b/remix-analyzer/test/analysis/astBlocks/doWhileLoopNode.json @@ -0,0 +1,204 @@ +{ + "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 diff --git a/remix-analyzer/test/analysis/astBlocks/externalDirect.json b/remix-analyzer/test/analysis/astBlocks/externalDirect.json new file mode 100644 index 0000000000..ceb1bf2cd2 --- /dev/null +++ b/remix-analyzer/test/analysis/astBlocks/externalDirect.json @@ -0,0 +1,20 @@ +{ + "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 diff --git a/remix-analyzer/test/analysis/astBlocks/forLoopNode.json b/remix-analyzer/test/analysis/astBlocks/forLoopNode.json new file mode 100644 index 0000000000..214467cbae --- /dev/null +++ b/remix-analyzer/test/analysis/astBlocks/forLoopNode.json @@ -0,0 +1,264 @@ +{ + "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 diff --git a/remix-analyzer/test/analysis/astBlocks/fullyQualifiedFunctionDefinition.json b/remix-analyzer/test/analysis/astBlocks/fullyQualifiedFunctionDefinition.json new file mode 100644 index 0000000000..81c77667a7 --- /dev/null +++ b/remix-analyzer/test/analysis/astBlocks/fullyQualifiedFunctionDefinition.json @@ -0,0 +1,74 @@ +{ + "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 diff --git a/remix-analyzer/test/analysis/astBlocks/functionDefinition.json b/remix-analyzer/test/analysis/astBlocks/functionDefinition.json new file mode 100644 index 0000000000..9c915d3992 --- /dev/null +++ b/remix-analyzer/test/analysis/astBlocks/functionDefinition.json @@ -0,0 +1,24 @@ +{ + "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 diff --git a/remix-analyzer/test/analysis/astBlocks/index.js b/remix-analyzer/test/analysis/astBlocks/index.js new file mode 100644 index 0000000000..f952ad63c5 --- /dev/null +++ b/remix-analyzer/test/analysis/astBlocks/index.js @@ -0,0 +1,22 @@ +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') +} diff --git a/remix-analyzer/test/analysis/astBlocks/inheritance.json b/remix-analyzer/test/analysis/astBlocks/inheritance.json new file mode 100644 index 0000000000..5a1fc15ce7 --- /dev/null +++ b/remix-analyzer/test/analysis/astBlocks/inheritance.json @@ -0,0 +1,15 @@ +{ + "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 diff --git a/remix-analyzer/test/analysis/astBlocks/inlineAssembly.json b/remix-analyzer/test/analysis/astBlocks/inlineAssembly.json new file mode 100644 index 0000000000..6136ab3060 --- /dev/null +++ b/remix-analyzer/test/analysis/astBlocks/inlineAssembly.json @@ -0,0 +1,7 @@ +{ + "children": [ + ], + "id": 21, + "name": "InlineAssembly", + "src": "809:41:0" + } \ No newline at end of file diff --git a/remix-analyzer/test/analysis/astBlocks/libCall.json b/remix-analyzer/test/analysis/astBlocks/libCall.json new file mode 100644 index 0000000000..ebb7cfbbd1 --- /dev/null +++ b/remix-analyzer/test/analysis/astBlocks/libCall.json @@ -0,0 +1,16 @@ +{ + "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 diff --git a/remix-analyzer/test/analysis/astBlocks/localCall.json b/remix-analyzer/test/analysis/astBlocks/localCall.json new file mode 100644 index 0000000000..35372abe41 --- /dev/null +++ b/remix-analyzer/test/analysis/astBlocks/localCall.json @@ -0,0 +1,29 @@ +{ + "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 diff --git a/remix-analyzer/test/analysis/astBlocks/lowlevelCall.json b/remix-analyzer/test/analysis/astBlocks/lowlevelCall.json new file mode 100644 index 0000000000..e5795ba82e --- /dev/null +++ b/remix-analyzer/test/analysis/astBlocks/lowlevelCall.json @@ -0,0 +1,42 @@ +{ + "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 diff --git a/remix-analyzer/test/analysis/astBlocks/parameterFunction.json b/remix-analyzer/test/analysis/astBlocks/parameterFunction.json new file mode 100644 index 0000000000..a5c44f8255 --- /dev/null +++ b/remix-analyzer/test/analysis/astBlocks/parameterFunction.json @@ -0,0 +1,71 @@ +{ + "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 diff --git a/remix-analyzer/test/analysis/astBlocks/parameterFunctionCall.json b/remix-analyzer/test/analysis/astBlocks/parameterFunctionCall.json new file mode 100644 index 0000000000..c9246dbed6 --- /dev/null +++ b/remix-analyzer/test/analysis/astBlocks/parameterFunctionCall.json @@ -0,0 +1,89 @@ +{ + "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 diff --git a/remix-analyzer/test/analysis/astBlocks/selfdestruct.json b/remix-analyzer/test/analysis/astBlocks/selfdestruct.json new file mode 100644 index 0000000000..66f29de42d --- /dev/null +++ b/remix-analyzer/test/analysis/astBlocks/selfdestruct.json @@ -0,0 +1,23 @@ +{ + "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 diff --git a/remix-analyzer/test/analysis/astBlocks/stateVariableContractNode.json b/remix-analyzer/test/analysis/astBlocks/stateVariableContractNode.json new file mode 100644 index 0000000000..1474c59b23 --- /dev/null +++ b/remix-analyzer/test/analysis/astBlocks/stateVariableContractNode.json @@ -0,0 +1,108 @@ +{ + "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 diff --git a/remix-analyzer/test/analysis/astBlocks/storageVariableNodes.json b/remix-analyzer/test/analysis/astBlocks/storageVariableNodes.json new file mode 100644 index 0000000000..4448202b60 --- /dev/null +++ b/remix-analyzer/test/analysis/astBlocks/storageVariableNodes.json @@ -0,0 +1,74 @@ +{ + "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 diff --git a/remix-analyzer/test/analysis/astBlocks/superLocal.json b/remix-analyzer/test/analysis/astBlocks/superLocal.json new file mode 100644 index 0000000000..7a5b8b7bdf --- /dev/null +++ b/remix-analyzer/test/analysis/astBlocks/superLocal.json @@ -0,0 +1,16 @@ +{ + "attributes": { + "member_name": "duper", + "type": "function ()" + }, + "children": [ + { + "attributes": { + "type": "contract super a", + "value": "super" + }, + "name": "Identifier" + } + ], + "name": "MemberAccess" +} \ No newline at end of file diff --git a/remix-analyzer/test/analysis/astBlocks/thisLocalCall.json b/remix-analyzer/test/analysis/astBlocks/thisLocalCall.json new file mode 100644 index 0000000000..df88de3247 --- /dev/null +++ b/remix-analyzer/test/analysis/astBlocks/thisLocalCall.json @@ -0,0 +1,10 @@ +{ + "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 diff --git a/remix-analyzer/test/analysis/astBlocks/whileLoopNode.json b/remix-analyzer/test/analysis/astBlocks/whileLoopNode.json new file mode 100644 index 0000000000..85dcb5a327 --- /dev/null +++ b/remix-analyzer/test/analysis/astBlocks/whileLoopNode.json @@ -0,0 +1,204 @@ +{ + "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 diff --git a/remix-analyzer/test/analysis/staticAnalysisCommon-test.js b/remix-analyzer/test/analysis/staticAnalysisCommon-test.js index b1b3b9e08b..2fbcf06482 100644 --- a/remix-analyzer/test/analysis/staticAnalysisCommon-test.js +++ b/remix-analyzer/test/analysis/staticAnalysisCommon-test.js @@ -1,6 +1,9 @@ var test = require('tape') - 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) { return str.replace(/[-[\]/{}()+?.\\^$|]/g, '\\$&') @@ -157,72 +160,6 @@ test('staticAnalysisCommon.getType', function (t) { test('staticAnalysisCommon.getFunctionCallType', function (t) { 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(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') @@ -232,75 +169,6 @@ test('staticAnalysisCommon.getFunctionCallType', function (t) { test('staticAnalysisCommon.getEffectedVariableName', function (t) { 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.ok(common.getEffectedVariableName(assignment) === 'c', 'get right name for assignment') t.throws(() => common.getEffectedVariableName({ name: 'MemberAccess' }), undefined, 'should throw on all other nodes') @@ -308,56 +176,6 @@ test('staticAnalysisCommon.getEffectedVariableName', function (t) { test('staticAnalysisCommon.getLocalCallName', function (t) { 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.throws(() => common.getLocalCallName(externalDirect), undefined, 'throws on other nodes') t.throws(() => common.getLocalCallName(thisLocalCall), undefined, 'throws on other nodes') @@ -365,56 +183,6 @@ test('staticAnalysisCommon.getLocalCallName', function (t) { test('staticAnalysisCommon.getThisLocalCallName', function (t) { 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.throws(() => common.getThisLocalCallName(externalDirect), undefined, 'throws on other nodes') t.throws(() => common.getThisLocalCallName(localCall), undefined, 'throws on other nodes') @@ -422,72 +190,6 @@ test('staticAnalysisCommon.getThisLocalCallName', function (t) { test('staticAnalysisCommon.getSuperLocalCallName', function (t) { 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.throws(() => common.getSuperLocalCallName(thisLocalCall), 'throws on other nodes') t.throws(() => common.getSuperLocalCallName(externalDirect), undefined, 'throws on other nodes') @@ -496,57 +198,6 @@ test('staticAnalysisCommon.getSuperLocalCallName', function (t) { test('staticAnalysisCommon.getExternalDirectCallContractName', function (t) { 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.throws(() => common.getExternalDirectCallContractName(thisLocalCall), undefined, 'throws on other nodes') t.throws(() => common.getExternalDirectCallContractName(localCall), undefined, 'throws on other nodes') @@ -554,56 +205,6 @@ test('staticAnalysisCommon.getExternalDirectCallContractName', function (t) { test('staticAnalysisCommon.getThisLocalCallContractName', function (t) { 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.throws(() => common.getThisLocalCallContractName(localCall), undefined, 'throws on other nodes') t.throws(() => common.getThisLocalCallContractName(externalDirect), undefined, 'throws on other nodes') @@ -611,56 +212,6 @@ test('staticAnalysisCommon.getThisLocalCallContractName', function (t) { test('staticAnalysisCommon.getExternalDirectCallMemberName', function (t) { 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.throws(() => common.getExternalDirectCallMemberName(thisLocalCall), undefined, 'throws on other nodes') t.throws(() => common.getExternalDirectCallMemberName(localCall), undefined, 'throws on other nodes') @@ -682,163 +233,21 @@ test('staticAnalysisCommon.getFunctionDefinitionName', function (t) { test('staticAnalysisCommon.getInheritsFromName', function (t) { t.plan(2) - var inh = { - '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.ok(common.getInheritsFromName(inheritance) === 'r', 'returns right contract name') t.throws(() => common.getInheritsFromName({ name: 'ElementaryTypeName' }), undefined, 'throws on other nodes') }) test('staticAnalysisCommon.getDeclaredVariableName', function (t) { t.plan(2) - var 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' - } - t.ok(common.getDeclaredVariableName(node1) === 'x', 'extract right variable name') - node1.name = 'FunctionCall' + t.ok(common.getDeclaredVariableName(storageVariableNodes.node1) === 'x', 'extract right variable name') + let node1 = JSON.parse(JSON.stringify(storageVariableNodes)) + node1.node1.name = 'FunctionCall' t.throws(() => common.getDeclaredVariableName(node1) === 'x', undefined, 'throw if wrong node') }) test('staticAnalysisCommon.getStateVariableDeclarationsFormContractNode', function (t) { t.plan(4) - var contract = { - '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) - + var res = common.getStateVariableDeclarationsFormContractNode(stateVariableContractNode).map(common.getDeclaredVariableName) t.ok(res[0] === 'chairperson', 'var 1 should be ') t.ok(res[1] === 'voters', 'var 2 should be ') t.ok(res[2] === 'proposals', 'var 3 should be ') @@ -847,86 +256,12 @@ test('staticAnalysisCommon.getStateVariableDeclarationsFormContractNode', functi test('staticAnalysisCommon.getFunctionOrModifierDefinitionParameterPart', function (t) { t.plan(2) - var funDef = { - '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.ok(common.helpers.nodeType(common.getFunctionOrModifierDefinitionParameterPart(functionDefinition), 'ParameterList'), 'should return a parameterList') t.throws(() => common.getFunctionOrModifierDefinitionParameterPart({ name: 'SourceUnit' }), undefined, 'throws on other nodes') }) test('staticAnalysisCommon.getFunctionCallTypeParameterType', function (t) { 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(externalDirect) === '', 'external direct 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) { test('staticAnalysisCommon.getLibraryCallContractName', function (t) { t.plan(2) - var node = { - '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.equal(common.getLibraryCallContractName(libCall), 'Set', 'should return correct contract name') t.throws(() => common.getLibraryCallContractName({ name: 'Identifier' }), undefined, 'should throw on wrong node') }) test('staticAnalysisCommon.getLibraryCallMemberName', function (t) { t.plan(2) - var node = { - '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.equal(common.getLibraryCallMemberName(libCall), 'insert', 'should return correct member name') t.throws(() => common.getLibraryCallMemberName({ name: 'Identifier' }), undefined, 'should throw on wrong node') }) test('staticAnalysisCommon.getFullQualifiedFunctionCallIdent', function (t) { t.plan(4) 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, 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') @@ -1040,763 +292,16 @@ test('staticAnalysisCommon.getFullQualifiedFunctionCallIdent', function (t) { test('staticAnalysisCommon.getFullQuallyfiedFuncDefinitionIdent', function (t) { t.plan(3) var contract = { name: 'ContractDefinition', attributes: { name: 'baz' } } - var funDef = { - '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.ok(common.getFullQuallyfiedFuncDefinitionIdent(contract, fullyQualifiedFunctionDefinition, ['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({ 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) { t.plan(3) - var node1 = { - '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' - } - 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 + t.equal(common.getLoopBlockStartIndex(forLoopNode), 3) // 'for' loop + t.equal(common.getLoopBlockStartIndex(doWhileLoopNode), 1) // 'do-while' loop + t.equal(common.getLoopBlockStartIndex(whileLoopNode), 1) // 'while' loop }) // #################### Trivial Node Identification @@ -1891,954 +396,38 @@ test('staticAnalysisCommon.isInlineAssembly', function (t) { test('staticAnalysisCommon.isLoop', function (t) { t.plan(3) - var node1 = { - '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' - } - 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) + t.equal(common.isLoop(forLoopNode), true) + t.equal(common.isLoop(doWhileLoopNode), true) + t.equal(common.isLoop(whileLoopNode), true) }) // #################### Complex Node Identification test('staticAnalysisCommon.isBuiltinFunctionCall', function (t) { 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.notOk(common.isBuiltinFunctionCall(localCall), 'local call is not builtin') }) test('staticAnalysisCommon.isStorageVariableDeclaration', function (t) { t.plan(3) - var 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' - } - 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') + t.ok(common.isStorageVariableDeclaration(storageVariableNodes.node1), 'struct storage pointer param is storage') + t.ok(common.isStorageVariableDeclaration(storageVariableNodes.node2), 'struct storage pointer mapping param is storage') + t.notOk(common.isStorageVariableDeclaration(storageVariableNodes.node3), 'bytes is not storage') }) test('staticAnalysisCommon.isInteraction', function (t) { t.plan(6) - var sendAst = { name: 'MemberAccess', children: [{attributes: { value: 'd', type: 'address' }}], attributes: { value: 'send', type: 'function (uint256) returns (bool)' } } - var callAst = { name: 'MemberAccess', children: [{attributes: { value: 'f', type: 'address' }}], attributes: { member_name: 'call', type: 'function () payable returns (bool)' } } - var callcodeAst = { name: 'MemberAccess', children: [{attributes: { value: 'f', type: 'address' }}], attributes: { member_name: 'callcode', type: 'function () payable returns (bool)' } } - var delegatecallAst = { name: 'MemberAccess', children: [{attributes: { value: 'g', type: 'address' }}], attributes: { member_name: 'delegatecall', type: 'function () returns (bool)' } } - var nodeExtDir = { - 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 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') + t.ok(common.isInteraction(lowlevelCall.sendAst), 'send is interaction') + t.ok(common.isInteraction(lowlevelCall.callAst), 'call is interaction') + t.ok(common.isInteraction(externalDirect), 'ExternalDirecCall is interaction') + t.notOk(common.isInteraction(lowlevelCall.callcodeAst), 'callcode is not interaction') + t.notOk(common.isInteraction(lowlevelCall.delegatecallAst), 'callcode is not interaction') + t.notOk(common.isInteraction(localCall), 'local call is not interaction') }) test('staticAnalysisCommon.isEffect', function (t) { 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: '++' } } t.ok(common.isEffect(inlineAssembly), 'inline assembly is treated as effect') t.ok(common.isEffect(assignment), 'assignment is treated as effect') @@ -2850,120 +439,11 @@ test('staticAnalysisCommon.isEffect', function (t) { test('staticAnalysisCommon.isWriteOnStateVariable', function (t) { t.plan(3) - 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 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' - } + let node1 = JSON.parse(JSON.stringify(storageVariableNodes.node1)) + let node2 = node1 + let node3 = node1 + node2.attributes.name = 'y' + node3.attributes.name = 'xx' 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') node3.attributes.name = 'c' @@ -2972,55 +452,9 @@ test('staticAnalysisCommon.isWriteOnStateVariable', function (t) { test('staticAnalysisCommon.isStateVariable', function (t) { t.plan(3) - 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.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') + t.ok(common.isStateVariable('x', [storageVariableNodes.node1, storageVariableNodes.node2]), 'is contained') + t.ok(common.isStateVariable('x', [storageVariableNodes.node2, storageVariableNodes.node1, storageVariableNodes.node1]), 'is contained twice') + t.notOk(common.isStateVariable('x', [storageVariableNodes.node2, storageVariableNodes.node3]), 'not contained') }) test('staticAnalysisCommon.isConstantFunction', function (t) { @@ -3069,63 +503,18 @@ test('staticAnalysisCommon.isFullyImplementedContract', function (t) { test('staticAnalysisCommon.isCallToNonConstLocalFunction', function (t) { t.plan(2) - var node1 = { - '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.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') + t.ok(common.isCallToNonConstLocalFunction(localCall), 'should be call to non const Local func') + localCall.children[0].attributes.type = 'function (struct Ballot.Voter storage pointer) constant payable (uint256)' + t.notok(common.isCallToNonConstLocalFunction(localCall), 'should no longer be call to non const Local func') }) test('staticAnalysisCommon.isExternalDirectCall', function (t) { 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)' } } - 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') - t.ok(common.isExternalDirectCall(node), 'f.info() should be external direct call') + t.notOk(common.isThisLocalCall(externalDirect), 'is this.local_method() used should not work') + t.notOk(common.isBlockTimestampAccess(externalDirect), 'is block.timestamp used should not work') + t.notOk(common.isNowAccess(externalDirect), 'is now used should not work') + t.ok(common.isExternalDirectCall(externalDirect), 'f.info() should be external direct call') t.notOk(common.isExternalDirectCall(node2), 'local call is not an exernal call') }) @@ -3147,320 +536,71 @@ test('staticAnalysisCommon.isBlockTimestampAccess', function (t) { test('staticAnalysisCommon.isBlockBlockhashAccess', function (t) { t.plan(4) - var node = { - 'attributes': { - 'member_name': 'blockhash', - 'type': 'function (uint256) returns (bytes32)' - }, - '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') + t.notOk(common.isThisLocalCall(blockHashAccess), 'is this.local_method() used should not work') + t.notOk(common.isBlockTimestampAccess(blockHashAccess), 'is block.timestamp used should not work') + t.ok(common.isBlockBlockHashAccess(blockHashAccess), 'blockhash should work') // todo: + t.notOk(common.isNowAccess(blockHashAccess), 'is now used should not work') }) test('staticAnalysisCommon.isThisLocalCall', function (t) { 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(node), 'is this.local_method() used should work') - t.notOk(common.isBlockTimestampAccess(node), 'is block.timestamp used should not work') - t.notOk(common.isNowAccess(node), 'is now used should not work') + t.ok(common.isThisLocalCall(thisLocalCall), 'is this.local_method() used should work') + t.notOk(common.isBlockTimestampAccess(thisLocalCall), 'is block.timestamp used should not work') + t.notOk(common.isNowAccess(thisLocalCall), 'is now used should not work') }) test('staticAnalysisCommon.isSuperLocalCall', function (t) { t.plan(4) - var node = { - 'attributes': { - 'member_name': 'duper', - 'type': 'function ()' - }, - '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') + t.ok(common.isSuperLocalCall(superLocal), 'is super.local_method() used should work') + t.notOk(common.isThisLocalCall(superLocal), 'is this.local_method() used should not work') + t.notOk(common.isBlockTimestampAccess(superLocal), 'is block.timestamp used should not work') + t.notOk(common.isNowAccess(superLocal), 'is now used should not work') }) test('staticAnalysisCommon.isLibraryCall', function (t) { t.plan(5) - var node = { - '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.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') + t.ok(common.isLibraryCall(libCall), 'is lib call should not work') + t.notOk(common.isSuperLocalCall(libCall), 'is super.local_method() used should not work') + t.notOk(common.isThisLocalCall(libCall), 'is this.local_method() used should not work') + t.notOk(common.isBlockTimestampAccess(libCall), 'is block.timestamp used should not work') + t.notOk(common.isNowAccess(libCall), 'is now used should not work') }) test('staticAnalysisCommon.isLocalCall', function (t) { t.plan(5) - var node1 = { - '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.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') + t.ok(common.isLocalCall(localCall), 'isLocalCall') + t.notOk(common.isLowLevelCall(localCall), 'is not low level call') + t.notOk(common.isExternalDirectCall(localCall), 'is not external direct call') + t.notOk(common.isEffect(localCall), 'is not effect') + t.notOk(common.isInteraction(localCall), 'is not interaction') }) test('staticAnalysisCommon.isLowLevelCall', function (t) { t.plan(6) - var sendAst = { name: 'MemberAccess', children: [{attributes: { value: 'd', type: 'address' }}], attributes: { value: 'send', type: 'function (uint256) returns (bool)' } } - var callAst = { name: 'MemberAccess', children: [{attributes: { value: 'f', type: 'address' }}], attributes: { member_name: 'call', type: 'function () payable returns (bool)' } } - var callcodeAst = { name: 'MemberAccess', children: [{attributes: { value: 'f', type: 'address' }}], attributes: { member_name: 'callcode', type: 'function () payable returns (bool)' } } - var delegatecallAst = { name: 'MemberAccess', children: [{attributes: { value: 'g', type: 'address' }}], attributes: { member_name: 'delegatecall', type: 'function () returns (bool)' } } - - t.ok(common.isLowLevelSendInst(sendAst) && common.isLowLevelCall(sendAst), 'send 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') + t.ok(common.isLowLevelSendInst(lowlevelCall.sendAst) && common.isLowLevelCall(lowlevelCall.sendAst), 'send is llc should work') + t.ok(common.isLowLevelCallInst(lowlevelCall.callAst) && common.isLowLevelCall(lowlevelCall.callAst), 'call is llc should work') + t.notOk(common.isLowLevelCallInst(lowlevelCall.callcodeAst), 'callcode is not call') + 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.isLowLevelDelegatecallInst(lowlevelCall.delegatecallAst) && common.isLowLevelCall(lowlevelCall.delegatecallAst), 'delegatecall is llc should work') }) test('staticAnalysisCommon: Call of parameter function', function (t) { t.plan(7) - var node1 = { - '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' - } - - 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') + t.ok(common.isLocalCall(parameterFunction), 'is not LocalCall') + t.notOk(common.isThisLocalCall(parameterFunction), 'is not this local call') + t.notOk(common.isSuperLocalCall(parameterFunction), 'is not super local call') + t.notOk(common.isExternalDirectCall(parameterFunction), 'is not ExternalDirectCall') + t.notOk(common.isLibraryCall(parameterFunction), 'is not LibraryCall') + + t.equals(common.getFunctionCallType(parameterFunction), 'function (uint256,uint256) pure returns (uint256)', 'Extracts right type') + t.equals(common.getFunctionCallTypeParameterType(parameterFunction), 'uint256,uint256', 'Extracts param right type') }) test('staticAnalysisCommon: function call with of function with function parameter', function (t) { t.plan(2) - var node1 = { - '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' - } - - 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') + t.equals(common.getFunctionCallType(parameterFunctionCall), 'function (function (uint256,uint256) pure returns (uint256),uint256,uint256) pure returns (uint256)', 'Extracts right type') + t.equals(common.getFunctionCallTypeParameterType(parameterFunctionCall), 'function (uint256,uint256) pure returns (uint256),uint256,uint256', 'Extracts param right type') }) test('staticAnalysisCommon: require call', function (t) {