Commit d68814df authored by Michael Fröwis's avatar Michael Fröwis Committed by chriseth

Static Analysis: more unit tests

parent 11917ffc
...@@ -67,12 +67,12 @@ function getType (node) { ...@@ -67,12 +67,12 @@ function getType (node) {
function getFunctionCallType (func) { function getFunctionCallType (func) {
if (!(isExternalDirectCall(func) || isThisLocalCall(func) || isLocalCall(func))) throw new Error('staticAnalysisCommon.js: not function call Node') if (!(isExternalDirectCall(func) || isThisLocalCall(func) || isLocalCall(func))) throw new Error('staticAnalysisCommon.js: not function call Node')
if (isExternalDirectCall(func)) return func.attributes.type if (isExternalDirectCall(func) || isThisLocalCall(func)) return func.attributes.type
return findFirstSubNodeLTR(func, exactMatch(nodeTypes.IDENTIFIER)).attributes.type return findFirstSubNodeLTR(func, exactMatch(nodeTypes.IDENTIFIER)).attributes.type
} }
function getEffectedVariableName (effectNode) { function getEffectedVariableName (effectNode) {
if (!isEffect(effectNode)) throw new Error('staticAnalysisCommon.js: not an effect Node') if (!isEffect(effectNode) || isInlineAssembly(effectNode)) throw new Error('staticAnalysisCommon.js: not an effect Node or inline assembly')
return findFirstSubNodeLTR(effectNode, exactMatch(nodeTypes.IDENTIFIER)).attributes.value return findFirstSubNodeLTR(effectNode, exactMatch(nodeTypes.IDENTIFIER)).attributes.value
} }
...@@ -91,6 +91,11 @@ function getExternalDirectCallContractName (extDirectCall) { ...@@ -91,6 +91,11 @@ function getExternalDirectCallContractName (extDirectCall) {
return extDirectCall.children[0].attributes.type.replace(new RegExp(basicRegex.CONTRACTTYPE), '') return extDirectCall.children[0].attributes.type.replace(new RegExp(basicRegex.CONTRACTTYPE), '')
} }
function getThisLocalCallContractName (thisLocalCall) {
if (!isThisLocalCall(thisLocalCall)) throw new Error('staticAnalysisCommon.js: not an this local call Node')
return thisLocalCall.children[0].attributes.type.replace(new RegExp(basicRegex.CONTRACTTYPE), '')
}
function getExternalDirectCallMemberName (extDirectCall) { function getExternalDirectCallMemberName (extDirectCall) {
if (!isExternalDirectCall(extDirectCall)) throw new Error('staticAnalysisCommon.js: not an external direct call Node') if (!isExternalDirectCall(extDirectCall)) throw new Error('staticAnalysisCommon.js: not an external direct call Node')
return extDirectCall.attributes.member_name return extDirectCall.attributes.member_name
...@@ -132,7 +137,7 @@ function getFunctionCallTypeParameterType (func) { ...@@ -132,7 +137,7 @@ function getFunctionCallTypeParameterType (func) {
function getFullQualifiedFunctionCallIdent (contract, func) { function getFullQualifiedFunctionCallIdent (contract, func) {
if (isLocalCall(func)) return getContractName(contract) + '.' + getLocalCallName(func) + '(' + getFunctionCallTypeParameterType(func) + ')' if (isLocalCall(func)) return getContractName(contract) + '.' + getLocalCallName(func) + '(' + getFunctionCallTypeParameterType(func) + ')'
else if (isThisLocalCall(func)) return getContractName(contract) + '.' + getThisLocalCallName(func) + '(' + getFunctionCallTypeParameterType(func) + ')' else if (isThisLocalCall(func)) return getThisLocalCallContractName(func) + '.' + getThisLocalCallName(func) + '(' + getFunctionCallTypeParameterType(func) + ')'
else if (isExternalDirectCall(func)) return getExternalDirectCallContractName(func) + '.' + getExternalDirectCallMemberName(func) + '(' + getFunctionCallTypeParameterType(func) + ')' else if (isExternalDirectCall(func)) return getExternalDirectCallContractName(func) + '.' + getExternalDirectCallMemberName(func) + '(' + getFunctionCallTypeParameterType(func) + ')'
else throw new Error('staticAnalysisCommon.js: Can not get function name form non function call node') else throw new Error('staticAnalysisCommon.js: Can not get function name form non function call node')
} }
...@@ -201,6 +206,18 @@ function isConstantFunction (node) { ...@@ -201,6 +206,18 @@ function isConstantFunction (node) {
return isFunctionDefinition(node) && node.attributes.constant === true return isFunctionDefinition(node) && node.attributes.constant === true
} }
function isPlusPlusUnaryOperation (node) {
return nodeType(node, exactMatch(nodeTypes.UNARYOPERATION)) && operator(node, exactMatch(utils.escapeRegExp('++')))
}
function isMinusMinusUnaryOperation (node) {
return nodeType(node, exactMatch(nodeTypes.UNARYOPERATION)) && operator(node, exactMatch(utils.escapeRegExp('--')))
}
function isFullyImplementedContract (node) {
return nodeType(node, exactMatch(nodeTypes.CONTRACTDEFINITION)) && node.attributes.fullyImplemented === true
}
function isCallToNonConstLocalFunction (node) { function isCallToNonConstLocalFunction (node) {
return isLocalCall(node) && !expressionType(node.children[0], basicRegex.CONSTANTFUNCTIONTYPE) return isLocalCall(node) && !expressionType(node.children[0], basicRegex.CONSTANTFUNCTIONTYPE)
} }
...@@ -216,27 +233,11 @@ function isNowAccess (node) { ...@@ -216,27 +233,11 @@ function isNowAccess (node) {
name(node, exactMatch('now')) name(node, exactMatch('now'))
} }
function isPlusPlusUnaryOperation (node) {
return nodeType(node, exactMatch(nodeTypes.UNARYOPERATION)) && operator(node, exactMatch(utils.escapeRegExp('++')))
}
function isMinusMinusUnaryOperation (node) {
return nodeType(node, exactMatch(nodeTypes.UNARYOPERATION)) && operator(node, exactMatch('--'))
}
function isFullyImplementedContract (node) {
return nodeType(node, exactMatch(nodeTypes.CONTRACTDEFINITION)) && node.attributes.fullyImplemented === true
}
// usage of block timestamp // usage of block timestamp
function isBlockTimestampAccess (node) { function isBlockTimestampAccess (node) {
return isSpecialVariableAccess(node, specialVariables.BLOCKTIMESTAMP) return isSpecialVariableAccess(node, specialVariables.BLOCKTIMESTAMP)
} }
function isSpecialVariableAccess (node, varType) {
return isMemberAccess(node, varType.type, varType.obj, varType.obj, varType.member)
}
function isThisLocalCall (node) { function isThisLocalCall (node) {
return isMemberAccess(node, basicRegex.FUNCTIONTYPE, exactMatch('this'), basicRegex.CONTRACTTYPE, undefined) return isMemberAccess(node, basicRegex.FUNCTIONTYPE, exactMatch('this'), basicRegex.CONTRACTTYPE, undefined)
} }
...@@ -281,6 +282,8 @@ function isLLDelegatecall (node) { ...@@ -281,6 +282,8 @@ function isLLDelegatecall (node) {
undefined, exactMatch(basicTypes.ADDRESS), exactMatch(lowLevelCallTypes.DELEGATECALL.ident)) undefined, exactMatch(basicTypes.ADDRESS), exactMatch(lowLevelCallTypes.DELEGATECALL.ident))
} }
// #################### Complex Node Identification - Private
function isMemberAccess (node, retType, accessor, accessorType, memberName) { function isMemberAccess (node, retType, accessor, accessorType, memberName) {
return nodeType(node, exactMatch(nodeTypes.MEMBERACCESS)) && return nodeType(node, exactMatch(nodeTypes.MEMBERACCESS)) &&
expressionType(node, retType) && expressionType(node, retType) &&
...@@ -290,6 +293,10 @@ function isMemberAccess (node, retType, accessor, accessorType, memberName) { ...@@ -290,6 +293,10 @@ function isMemberAccess (node, retType, accessor, accessorType, memberName) {
expressionType(node.children[0], accessorType) expressionType(node.children[0], accessorType)
} }
function isSpecialVariableAccess (node, varType) {
return isMemberAccess(node, varType.type, varType.obj, varType.obj, varType.member)
}
// #################### Node Identification Primitives // #################### Node Identification Primitives
function nrOfChildren (node, nr) { function nrOfChildren (node, nr) {
...@@ -337,6 +344,7 @@ function buildFunctionSignature (paramTypes, returnTypes, isPayable) { ...@@ -337,6 +344,7 @@ function buildFunctionSignature (paramTypes, returnTypes, isPayable) {
} }
function findFirstSubNodeLTR (node, type) { function findFirstSubNodeLTR (node, type) {
if (!node || !node.children) return null
for (let i = 0; i < node.children.length; ++i) { for (let i = 0; i < node.children.length; ++i) {
var item = node.children[i] var item = node.children[i]
if (nodeType(item, type)) return item if (nodeType(item, type)) return item
...@@ -360,6 +368,7 @@ module.exports = { ...@@ -360,6 +368,7 @@ module.exports = {
getLocalCallName: getLocalCallName, getLocalCallName: getLocalCallName,
getInheritsFromName: getInheritsFromName, getInheritsFromName: getInheritsFromName,
getExternalDirectCallContractName: getExternalDirectCallContractName, getExternalDirectCallContractName: getExternalDirectCallContractName,
getThisLocalCallContractName: getThisLocalCallContractName,
getExternalDirectCallMemberName: getExternalDirectCallMemberName, getExternalDirectCallMemberName: getExternalDirectCallMemberName,
getFunctionDefinitionName: getFunctionDefinitionName, getFunctionDefinitionName: getFunctionDefinitionName,
getFunctionCallTypeParameterType: getFunctionCallTypeParameterType, getFunctionCallTypeParameterType: getFunctionCallTypeParameterType,
...@@ -385,6 +394,8 @@ module.exports = { ...@@ -385,6 +394,8 @@ module.exports = {
isExternalDirectCall: isExternalDirectCall, isExternalDirectCall: isExternalDirectCall,
isFullyImplementedContract: isFullyImplementedContract, isFullyImplementedContract: isFullyImplementedContract,
isCallToNonConstLocalFunction: isCallToNonConstLocalFunction, isCallToNonConstLocalFunction: isCallToNonConstLocalFunction,
isPlusPlusUnaryOperation: isPlusPlusUnaryOperation,
isMinusMinusUnaryOperation: isMinusMinusUnaryOperation,
// #################### Trivial Node Identification // #################### Trivial Node Identification
isFunctionDefinition: isFunctionDefinition, isFunctionDefinition: isFunctionDefinition,
...@@ -406,9 +417,11 @@ module.exports = { ...@@ -406,9 +417,11 @@ module.exports = {
specialVariables: specialVariables, specialVariables: specialVariables,
helpers: { helpers: {
nrOfChildren: nrOfChildren, nrOfChildren: nrOfChildren,
minNrOfChildren: minNrOfChildren,
expressionType: expressionType, expressionType: expressionType,
nodeType: nodeType, nodeType: nodeType,
name: name, name: name,
operator: operator,
buildFunctionSignature: buildFunctionSignature buildFunctionSignature: buildFunctionSignature
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment