typo, type mismatch error, unit tests, types

pull/5370/head
aniket-engg 5 years ago committed by Aniket
parent b0eaf14569
commit 8bdc2f28a7
  1. 11
      remix-analyzer/src/solidity-analyzer/index.ts
  2. 67
      remix-analyzer/src/solidity-analyzer/modules/staticAnalysisCommon.ts
  3. 9
      remix-analyzer/src/types.ts
  4. 74
      remix-analyzer/test/analysis/staticAnalysisCommon-test.ts
  5. 18
      remix-analyzer/test/analysis/staticAnalysisIssues-test-0.4.24.ts
  6. 18
      remix-analyzer/test/analysis/staticAnalysisIssues-test-0.5.0.ts

@ -1,22 +1,13 @@
'use strict'
import { AstWalker } from 'remix-astwalker'
import list from './modules/list'
import { CompilationResult, AnalyzerModule, ReportObj } from 'types'
import { CompilationResult, AnalyzerModule, AnalysisReportObj, AnalysisReport } from 'types'
type ModuleObj = {
name: string
mod: AnalyzerModule
}
interface AnalysisReportObj extends ReportObj {
error? : string
}
type AnalysisReport = {
name: string
report: AnalysisReportObj[]
}
export default class staticAnalysisRunner {
run (compilationResult: CompilationResult, toRun: any[], callback: ((reports: AnalysisReport[]) => void)): void {

@ -190,30 +190,6 @@ function getEffectedVariableName (effectNode: AssignmentAstNode | UnaryOperation
} else throw new Error('staticAnalysisCommon.js: wrong node type')
}
/**
* Finds first node of a certain type under a specific node.
* @node {AstNode} node to start form
* @type {String} Type the ast node should have
* @return {AstNode} null or node found
* Note: developed keeping identifier node search in mind to get first identifier node from left in subscope
*/
function findFirstSubNodeLTR (node: any, type: string): any {
if(node.nodeType && nodeType(node, type))
return node
else if(node.nodeType && nodeType(node, exactMatch('Assignment')))
return findFirstSubNodeLTR(node.leftHandSide, type)
else if(node.nodeType && nodeType(node, exactMatch('MemberAccess')))
return findFirstSubNodeLTR(node.expression, type)
else if(node.nodeType && nodeType(node, exactMatch('IndexAccess')))
return findFirstSubNodeLTR(node.baseExpression, type)
else if(node.nodeType && nodeType(node, exactMatch('UnaryOperation')))
return findFirstSubNodeLTR(node.subExpression, type)
}
/**
* Returns the identifier of a local call, Throws on wrong node.
* Example: f(103) => f
@ -221,7 +197,7 @@ function findFirstSubNodeLTR (node: any, type: string): any {
* @return {string} name of the function called
*/
function getLocalCallName (localCallNode: FunctionCallAstNode): string {
if (!isLocalCall(localCallNode) && !isAbiNamespaceCall(localCallNode)) throw new Error('staticAnalysisCommon.js: not an local call Node')
if (!isLocalCall(localCallNode) && !isAbiNamespaceCall(localCallNode)) throw new Error('staticAnalysisCommon.js: not a local call Node')
return localCallNode.expression.name
}
@ -232,7 +208,7 @@ function getLocalCallName (localCallNode: FunctionCallAstNode): string {
* @return {string} name of the function called
*/
function getThisLocalCallName (thisLocalCallNode: FunctionCallAstNode): string {
if (!isThisLocalCall(thisLocalCallNode.expression)) throw new Error('staticAnalysisCommon.js: not an this local call Node')
if (!isThisLocalCall(thisLocalCallNode.expression)) throw new Error('staticAnalysisCommon.js: not a this local call Node')
return thisLocalCallNode.expression.memberName
}
@ -243,7 +219,7 @@ function getThisLocalCallName (thisLocalCallNode: FunctionCallAstNode): string {
* @return {string} name of the function called
*/
function getSuperLocalCallName (superLocalCallNode: FunctionCallAstNode): string {
if (!isSuperLocalCall(superLocalCallNode.expression)) throw new Error('staticAnalysisCommon.js: not an super local call Node')
if (!isSuperLocalCall(superLocalCallNode.expression)) throw new Error('staticAnalysisCommon.js: not a super local call Node')
return superLocalCallNode.expression.memberName
}
@ -271,7 +247,7 @@ function getExternalDirectCallContractName (extDirectCall: FunctionCallAstNode):
* @return {string} name of the contract the function is defined in
*/
function getThisLocalCallContractName (thisLocalCall: FunctionCallAstNode): string {
if (!isThisLocalCall(thisLocalCall.expression)) throw new Error('staticAnalysisCommon.js: not an this local call Node')
if (!isThisLocalCall(thisLocalCall.expression)) throw new Error('staticAnalysisCommon.js: not a this local call Node')
return thisLocalCall.expression.expression.typeDescriptions.typeString.replace(new RegExp(basicRegex.CONTRACTTYPE), '')
}
@ -296,6 +272,7 @@ function getExternalDirectCallMemberName (extDirectCall: FunctionCallAstNode): s
* @return {string} name of a contract defined
*/
function getContractName (contract: ContractDefinitionAstNode): string {
if (!nodeType(contract, exactMatch(nodeTypes.CONTRACTDEFINITION))) throw new Error('staticAnalysisCommon.js: not a ContractDefinition Node')
return contract.name
}
@ -307,6 +284,7 @@ function getContractName (contract: ContractDefinitionAstNode): string {
* @return {string} name of a function defined
*/
function getFunctionDefinitionName (funcDef: FunctionDefinitionAstNode): string {
if (!nodeType(funcDef, exactMatch(nodeTypes.FUNCTIONDEFINITION))) throw new Error('staticAnalysisCommon.js: not a FunctionDefinition Node')
return funcDef.name
}
@ -318,6 +296,7 @@ function getFunctionDefinitionName (funcDef: FunctionDefinitionAstNode): string
* @return {string} name of contract inherited from
*/
function getInheritsFromName (inheritsNode: InheritanceSpecifierAstNode): string {
if (!nodeType(inheritsNode, exactMatch(nodeTypes.INHERITANCESPECIFIER))) throw new Error('staticAnalysisCommon.js: not an InheritanceSpecifier Node')
return inheritsNode.baseName.name
}
@ -329,6 +308,7 @@ function getInheritsFromName (inheritsNode: InheritanceSpecifierAstNode): string
* @return {string} variable name
*/
function getDeclaredVariableName (varDeclNode: VariableDeclarationAstNode): string {
if (!nodeType(varDeclNode, exactMatch(nodeTypes.VARIABLEDECLARATION))) throw new Error('staticAnalysisCommon.js: not a VariableDeclaration Node')
return varDeclNode.name
}
@ -365,6 +345,7 @@ function getStateVariableDeclarationsFromContractNode (contractNode: ContractDef
* @return {parameterlist node} parameterlist node
*/
function getFunctionOrModifierDefinitionParameterPart (funcNode: FunctionDefinitionAstNode | ModifierDefinitionAstNode): ParameterListAstNode {
if (!nodeTypeIn(funcNode, [exactMatch(nodeTypes.FUNCTIONDEFINITION), exactMatch(nodeTypes.MODIFIERDEFINITION)])) throw new Error('staticAnalysisCommon.js: not a FunctionDefinition or ModifierDefinition Node')
return funcNode.parameters
}
@ -415,7 +396,7 @@ function getFunctionCallTypeParameterType (func: FunctionCallAstNode): string |
* @return {string} name of the lib defined
*/
function getLibraryCallContractName (node: FunctionCallAstNode): string | undefined {
if (!isLibraryCall(node.expression)) throw new Error('staticAnalysisCommon.js: not an this library call Node')
if (!isLibraryCall(node.expression)) throw new Error('staticAnalysisCommon.js: not a library call Node')
const types: RegExpExecArray | null = new RegExp(basicRegex.LIBRARYTYPE).exec(node.expression.expression.typeDescriptions.typeString)
if(types)
return types[1]
@ -432,7 +413,7 @@ function getLibraryCallContractName (node: FunctionCallAstNode): string | undefi
* @return {string} name of function called on the library
*/
function getLibraryCallMemberName (funcCall: FunctionCallAstNode): string {
// if (!isLibraryCall(funcCall)) throw new Error('staticAnalysisCommon.js: not an library call Node')
if (!isLibraryCall(funcCall.expression)) throw new Error('staticAnalysisCommon.js: not a library call Node')
return funcCall.expression.memberName
}
@ -1047,7 +1028,31 @@ function matches (...fnArgs: any[]): string {
}
/**
* Builds an function signature as used in the AST of the solc-json AST
* Finds first node of a certain type under a specific node.
* @node {AstNode} node to start form
* @type {String} Type the ast node should have
* @return {AstNode} null or node found
* Note: developed keeping identifier node search in mind to get first identifier node from left in subscope
*/
function findFirstSubNodeLTR (node: any, type: string): any {
if(node.nodeType && nodeType(node, type))
return node
else if(node.nodeType && nodeType(node, exactMatch('Assignment')))
return findFirstSubNodeLTR(node.leftHandSide, type)
else if(node.nodeType && nodeType(node, exactMatch('MemberAccess')))
return findFirstSubNodeLTR(node.expression, type)
else if(node.nodeType && nodeType(node, exactMatch('IndexAccess')))
return findFirstSubNodeLTR(node.baseExpression, type)
else if(node.nodeType && nodeType(node, exactMatch('UnaryOperation')))
return findFirstSubNodeLTR(node.subExpression, type)
}
/**
* Builds a function signature as used in the AST of the solc-json AST
* @param {Array} paramTypes
* list of parameter type names
* @param {Array} returnTypes

@ -24,6 +24,15 @@ export interface ReportObj {
more?: string
}
export interface AnalysisReportObj extends ReportObj {
error? : string
}
export type AnalysisReport = {
name: string
report: AnalysisReportObj[]
}
export interface CompilationResult {
error?: CompilationError,
/** not present if no errors/warnings were encountered */

@ -135,7 +135,7 @@ test('staticAnalysisCommon.helpers.expressionTypeDescription', function (t) {
// #################### Trivial Getter Test
test('staticAnalysisCommon.getType', function (t) {
t.plan(2)
t.plan(3)
const node = { "argumentTypes": null,
"id": 3,
"name": "a",
@ -151,6 +151,7 @@ test('staticAnalysisCommon.getType', function (t) {
}
t.ok(common.getType(blockHashAccess) === 'bytes32', 'gettype should work for different nodes')
t.ok(common.getType(node) === 'uint256', 'gettype should work for different nodes')
t.ok(common.getType(assignment) === 'uint256', 'gettype should work for different nodes')
})
// #################### Complex Getter Test
@ -165,114 +166,127 @@ test('staticAnalysisCommon.getFunctionCallType', function (t) {
test('staticAnalysisCommon.getEffectedVariableName', function (t) {
t.plan(3)
t.throws(() => common.getEffectedVariableName(inlineAssembly), Error, 'staticAnalysisCommon.js: not an effect Node or inline assembly, get from inline assembly should throw')
t.ok(common.getEffectedVariableName(assignment) === 'a', 'get right name for assignment')
t.throws(() => common.getEffectedVariableName(externalDirect), Error, 'should throw on all other nodes')
t.throws(() => common.getEffectedVariableName(inlineAssembly), new RegExp('staticAnalysisCommon.js: wrong node type'), 'staticAnalysisCommon.js: not an effect Node or inline assembly, get from inline assembly should throw')
t.throws(() => common.getEffectedVariableName(externalDirect), new RegExp('staticAnalysisCommon.js: not an effect Node'), 'should throw on all other nodes')
})
test('staticAnalysisCommon.getLocalCallName', function (t) {
t.plan(3)
t.ok(common.getLocalCallName(localCall) === 'e', 'getLocal call name from node')
t.throws(() => common.getLocalCallName(externalDirect), Error, 'throws on other nodes')
t.throws(() => common.getLocalCallName(thisLocalCall), Error, 'throws on other nodes')
t.throws(() => common.getLocalCallName(externalDirect), new RegExp('staticAnalysisCommon.js: not a local call Node'), 'throws for externalDirect nodes')
t.throws(() => common.getLocalCallName(thisLocalCall), new RegExp('staticAnalysisCommon.js: not a local call Node'), 'throws for this local call nodes')
})
test('staticAnalysisCommon.getThisLocalCallName', function (t) {
t.plan(3)
t.ok(common.getThisLocalCallName(thisLocalCall) === 'f', 'get this Local call name from node')
t.throws(() => common.getThisLocalCallName(externalDirect), Error, 'throws on other nodes')
t.throws(() => common.getThisLocalCallName(localCall), Error, 'throws on other nodes')
t.throws(() => common.getThisLocalCallName(externalDirect), new RegExp('staticAnalysisCommon.js: not a this local call Node'), 'throws on externalDirect nodes')
t.throws(() => common.getThisLocalCallName(localCall), new RegExp('staticAnalysisCommon.js: not a this local call Node'), 'throws on localCall nodes')
})
test('staticAnalysisCommon.getSuperLocalCallName', function (t) {
t.plan(4)
t.equal(common.getSuperLocalCallName(superLocal), 'x', 'get local name from super local call')
t.throws(() => common.getSuperLocalCallName(thisLocalCall), 'throws on other nodes')
t.throws(() => common.getSuperLocalCallName(externalDirect), 'throws on other nodes')
t.throws(() => common.getSuperLocalCallName(localCall), 'throws on other nodes')
t.throws(() => common.getSuperLocalCallName(thisLocalCall), new RegExp('staticAnalysisCommon.js: not a super local call Node'), 'throws on other nodes')
t.throws(() => common.getSuperLocalCallName(externalDirect), new RegExp('staticAnalysisCommon.js: not a super local call Node'),' throws on other nodes')
t.throws(() => common.getSuperLocalCallName(localCall), new RegExp('staticAnalysisCommon.js: not a super local call Node'), 'throws on other nodes')
})
test('staticAnalysisCommon.getExternalDirectCallContractName', function (t) {
t.plan(3)
t.ok(common.getExternalDirectCallContractName(externalDirect) === 'c', 'external direct call contract name from node')
t.throws(() => common.getExternalDirectCallContractName(thisLocalCall), Error, 'throws on other nodes')
t.throws(() => common.getExternalDirectCallContractName(localCall), Error, 'throws on other nodes')
t.throws(() => common.getExternalDirectCallContractName(thisLocalCall), new RegExp('staticAnalysisCommon.js: not an external direct call Node'), 'throws on other nodes')
t.throws(() => common.getExternalDirectCallContractName(localCall), new RegExp('staticAnalysisCommon.js: not an external direct call Node'), 'throws on other nodes')
})
test('staticAnalysisCommon.getThisLocalCallContractName', function (t) {
t.plan(3)
t.ok(common.getThisLocalCallContractName(thisLocalCall) === 'C', 'this local call contract name from node')
t.throws(() => common.getThisLocalCallContractName(localCall), Error, 'throws on other nodes')
t.throws(() => common.getThisLocalCallContractName(externalDirect), Error, 'throws on other nodes')
t.throws(() => common.getThisLocalCallContractName(localCall), new RegExp('staticAnalysisCommon.js: not a this local call Node'), 'throws on other nodes')
t.throws(() => common.getThisLocalCallContractName(externalDirect), new RegExp('staticAnalysisCommon.js: not a this local call Node'), 'throws on other nodes')
})
test('staticAnalysisCommon.getExternalDirectCallMemberName', function (t) {
t.plan(3)
t.ok(common.getExternalDirectCallMemberName(externalDirect) === 'f', 'external direct call name from node')
t.throws(() => common.getExternalDirectCallMemberName(thisLocalCall), Error, 'throws on other nodes')
t.throws(() => common.getExternalDirectCallMemberName(localCall), Error, 'throws on other nodes')
t.throws(() => common.getExternalDirectCallMemberName(thisLocalCall), new RegExp('staticAnalysisCommon.js: not an external direct call Node'), 'throws on other nodes')
t.throws(() => common.getExternalDirectCallMemberName(localCall), new RegExp('staticAnalysisCommon.js: not an external direct call Node'), 'throws on other nodes')
})
test('staticAnalysisCommon.getContractName', function (t) {
t.plan(1)
t.plan(2)
t.ok(common.getContractName(contractDefinition) === 'C', 'returns right contract name')
t.throws(() => common.getContractName(inheritance), new RegExp('staticAnalysisCommon.js: not a ContractDefinition Node'), 'throws on other nodes')
})
test('staticAnalysisCommon.getFunctionDefinitionName', function (t) {
t.plan(1)
t.plan(2)
t.ok(common.getFunctionDefinitionName(functionDefinition) === 'f', 'returns right function name')
t.throws(() => common.getFunctionDefinitionName(inheritance), new RegExp('staticAnalysisCommon.js: not a FunctionDefinition Node'), 'throws on other nodes')
})
test('staticAnalysisCommon.getInheritsFromName', function (t) {
t.plan(1)
t.plan(2)
t.ok(common.getInheritsFromName(inheritance) === 'A', 'returns right contract name')
t.throws(() => common.getInheritsFromName(functionDefinition), new RegExp('staticAnalysisCommon.js: not an InheritanceSpecifier Node'), 'throws on other nodes')
})
test('staticAnalysisCommon.getDeclaredVariableName', function (t) {
t.plan(1)
t.plan(2)
t.ok(common.getDeclaredVariableName(storageVariableNodes.node1) === 'c', 'extract right variable name')
let node1 = JSON.parse(JSON.stringify(storageVariableNodes))
node1.node1.nodeType = 'FunctionCall'
t.throws(() => common.getDeclaredVariableName(node1) === 'x', new RegExp('staticAnalysisCommon.js: not a VariableDeclaration Node'), 'throw if wrong node')
})
test('staticAnalysisCommon.getStateVariableDeclarationsFromContractNode', function (t) {
t.plan(3)
const res = common.getStateVariableDeclarationsFromContractNode(stateVariableContractNode).map(common.getDeclaredVariableName)
t.ok(res[0] === 'x', 'var 1 should be ')
t.ok(res[1] === 'b', 'var 2 should be ')
t.ok(res[2] === 's', 'var 3 should be ')
t.ok(res[0] === 'x', 'var 1 should be x')
t.ok(res[1] === 'b', 'var 2 should be b')
t.ok(res[2] === 's', 'var 3 should be s')
})
test('staticAnalysisCommon.getFunctionOrModifierDefinitionParameterPart', function (t) {
t.plan(1)
t.plan(2)
t.ok(common.helpers.nodeType(common.getFunctionOrModifierDefinitionParameterPart(functionDefinition), 'ParameterList'), 'should return a parameterList')
t.throws(() => common.getFunctionOrModifierDefinitionParameterPart(contractDefinition), new RegExp('staticAnalysisCommon.js: not a FunctionDefinition or ModifierDefinition Node'), 'throws on other nodes')
})
test('staticAnalysisCommon.getFunctionCallTypeParameterType', function (t) {
t.plan(3)
t.plan(4)
t.ok(common.getFunctionCallTypeParameterType(thisLocalCall) === '', 'this local call returns correct type')
t.ok(common.getFunctionCallTypeParameterType(externalDirect) === '', 'external direct call returns correct type')
t.ok(common.getFunctionCallTypeParameterType(localCall) === 'uint256,string memory', 'local call returns correct type')
t.throws(() => common.getFunctionCallTypeParameterType(thisLocalCall.expression), new RegExp('staticAnalysisCommon.js: cannot extract parameter types from function call'), 'throws on wrong type')
})
test('staticAnalysisCommon.getLibraryCallContractName', function (t) {
t.plan(1)
t.plan(2)
t.equal(common.getLibraryCallContractName(libCall), 'Set', 'should return correct contract name')
t.throws(() => common.getLibraryCallContractName(contractDefinition), new RegExp('staticAnalysisCommon.js: not a library call Node'), 'should throw on wrong node')
})
test('staticAnalysisCommon.getLibraryCallMemberName', function (t) {
t.plan(1)
t.plan(2)
t.equal(common.getLibraryCallMemberName(libCall), 'insert', 'should return correct member name')
t.throws(() => common.getLibraryCallMemberName(thisLocalCall), new RegExp('staticAnalysisCommon.js: not a library call Node'), 'should throw on wrong node')
})
test('staticAnalysisCommon.getFullQualifiedFunctionCallIdent', function (t) {
t.plan(3)
t.plan(4)
t.ok(common.getFullQualifiedFunctionCallIdent(contractDefinition, thisLocalCall) === 'C.f()', 'this local call returns correct type')
t.ok(common.getFullQualifiedFunctionCallIdent(contractDefinition, externalDirect) === 'c.f()', 'external direct call returns correct type')
t.ok(common.getFullQualifiedFunctionCallIdent(contractDefinition, localCall) === 'C.e(uint256,string memory)', 'local call returns correct type')
t.throws(() => common.getFullQualifiedFunctionCallIdent(contractDefinition, assignment), new RegExp('staticAnalysisCommon.js: Can not get function name from non function call node'), 'throws on wrong type')
})
test('staticAnalysisCommon.getFullQuallyfiedFuncDefinitionIdent', function (t) {
t.plan(1)
t.plan(3)
t.ok(common.getFullQuallyfiedFuncDefinitionIdent(contractDefinition, functionDefinition, ['uint256', 'bool']) === 'C.f(uint256,bool)', 'creates right signature')
t.throws(() => common.getFullQuallyfiedFuncDefinitionIdent(contractDefinition, parameterFunctionCall, ['uint256', 'bool']), new RegExp('staticAnalysisCommon.js: not a FunctionDefinition Node'), 'throws on wrong nodes')
t.throws(() => common.getFullQuallyfiedFuncDefinitionIdent(parameterFunctionCall, functionDefinition, ['uint256', 'bool']), new RegExp('staticAnalysisCommon.js: not a ContractDefinition Node'), 'throws on wrong nodes')
})
// #################### Complex Node Identification
@ -376,7 +390,7 @@ test('staticAnalysisCommon.isExternalDirectCall', function (t) {
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), 'c.f() should be external direct call')
t.notOk(common.isExternalDirectCall(thisLocalCall.expression), 'this local call is not an exernal call')
t.notOk(common.isExternalDirectCall(thisLocalCall.expression), 'this local call is not an external call')
})
test('staticAnalysisCommon.isNowAccess', function (t) {

@ -3,30 +3,30 @@ import { helpers } from 'remix-lib'
import { readFileSync } from 'fs'
import { join } from 'path'
import { default as StatRunner } from '../../dist/src/solidity-analyzer'
import { CompilationResult, AnalysisReportObj, AnalysisReport } from '../../src/types'
import { install, require as requireNPMmodule } from 'npm-install-version'
install('solc@0.4.24')
const compiler = requireNPMmodule('solc@0.4.24')
const { compilerInput } = helpers.compiler
const folder = 'solidity-v0.4.24'
const folder: string = 'solidity-v0.4.24'
function compile (fileName) {
const content = readFileSync(join(__dirname, 'test-contracts/' + folder, fileName), 'utf8')
function compile (fileName: string): CompilationResult {
const content: string = readFileSync(join(__dirname, 'test-contracts/' + folder, fileName), 'utf8')
return JSON.parse(compiler.compileStandardWrapper(compilerInput(content)))
}
test('staticAnalysisIssues.functionParameterPassingError', function (t) {
// https://github.com/ethereum/remix-ide/issues/889#issuecomment-351746474
t.plan(2)
const res = compile('functionParameters.sol')
const res: CompilationResult = compile('functionParameters.sol')
const Module = require('../../dist/src/solidity-analyzer/modules/checksEffectsInteraction').default
const statRunner = new StatRunner()
const statRunner: StatRunner = new StatRunner()
t.doesNotThrow(() => {
statRunner.runWithModuleList(res, [{ name: new Module().name, mod: new Module() }], (reports) => {
})
statRunner.runWithModuleList(res, [{ name: new Module().name, mod: new Module() }], (reports: AnalysisReport[]) => {})
}, 'Analysis should not throw')
statRunner.runWithModuleList(res, [{ name: new Module().name, mod: new Module() }], (reports) => {
t.ok(!reports.some((mod) => mod.report.some((rep) => rep.warning.includes('INTERNAL ERROR')), 'Should not have internal errors'))
statRunner.runWithModuleList(res, [{ name: new Module().name, mod: new Module() }], (reports: AnalysisReport[]) => {
t.ok(!reports.some((mod: AnalysisReport) => mod.report.some((rep: AnalysisReportObj) => rep.warning.includes('INTERNAL ERROR')), 'Should not have internal errors'))
})
})

@ -3,30 +3,30 @@ import { helpers } from 'remix-lib'
import { readFileSync } from 'fs'
import { join } from 'path'
import { default as StatRunner } from '../../dist/src/solidity-analyzer'
import { CompilationResult, AnalysisReportObj, AnalysisReport } from '../../src/types'
import { install, require as requireNPMmodule } from 'npm-install-version'
install('solc@0.5.0')
const compiler = requireNPMmodule('solc@0.5.0')
const {compilerInput } = helpers.compiler
const folder = 'solidity-v0.5'
const folder: string = 'solidity-v0.5'
function compile (fileName) {
const content = readFileSync(join(__dirname, 'test-contracts/' + folder, fileName), 'utf8')
function compile (fileName): CompilationResult {
const content: string = readFileSync(join(__dirname, 'test-contracts/' + folder, fileName), 'utf8')
return JSON.parse(compiler.compile(compilerInput(content)))
}
test('staticAnalysisIssues.functionParameterPassingError', function (t) {
// https://github.com/ethereum/remix-ide/issues/889#issuecomment-351746474
t.plan(2)
const res = compile('functionParameters.sol')
const res: CompilationResult = compile('functionParameters.sol')
const Module = require('../../dist/src/solidity-analyzer/modules/checksEffectsInteraction').default
const statRunner = new StatRunner()
const statRunner: StatRunner = new StatRunner()
t.doesNotThrow(() => {
statRunner.runWithModuleList(res, [{ name: new Module().name, mod: new Module() }], (reports) => {
})
statRunner.runWithModuleList(res, [{ name: new Module().name, mod: new Module() }], (reports: AnalysisReport[]) => {})
}, 'Analysis should not throw')
statRunner.runWithModuleList(res, [{ name: new Module().name, mod: new Module() }], (reports) => {
t.ok(!reports.some((mod) => mod.report.some((rep) => rep.warning.includes('INTERNAL ERROR')), 'Should not have internal errors'))
statRunner.runWithModuleList(res, [{ name: new Module().name, mod: new Module() }], (reports: AnalysisReport[]) => {
t.ok(!reports.some((mod: AnalysisReport) => mod.report.some((rep: AnalysisReportObj) => rep.warning.includes('INTERNAL ERROR')), 'Should not have internal errors'))
})
})

Loading…
Cancel
Save