|
|
@ -12,23 +12,23 @@ class Injector { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
_getInjectable(fileName, hash, type){ |
|
|
|
_getInjectable(id, hash, type){ |
|
|
|
return `${this._getMethodIdentifier(fileName)}(${hash}); /* ${type} */ \n`; |
|
|
|
return `${this._getMethodIdentifier(id)}(${hash}); /* ${type} */ \n`; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
_getHash(fileName) { |
|
|
|
_getHash(id) { |
|
|
|
this.hashCounter++; |
|
|
|
this.hashCounter++; |
|
|
|
return web3Utils.keccak256(`${fileName}:${this.hashCounter}`); |
|
|
|
return web3Utils.keccak256(`${id}:${this.hashCounter}`); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
_getMethodIdentifier(fileName){ |
|
|
|
_getMethodIdentifier(id){ |
|
|
|
return `coverage_${web3Utils.keccak256(fileName).slice(0,10)}` |
|
|
|
return `coverage_${web3Utils.keccak256(id).slice(0,10)}` |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
_getInjectionComponents(contract, injectionPoint, fileName, type){ |
|
|
|
_getInjectionComponents(contract, injectionPoint, id, type){ |
|
|
|
const { start, end } = this._split(contract, injectionPoint); |
|
|
|
const { start, end } = this._split(contract, injectionPoint); |
|
|
|
const hash = this._getHash(fileName) |
|
|
|
const hash = this._getHash(id) |
|
|
|
const injectable = this._getInjectable(fileName, hash, type); |
|
|
|
const injectable = this._getInjectable(id, hash, type); |
|
|
|
|
|
|
|
|
|
|
|
return { |
|
|
|
return { |
|
|
|
start: start, |
|
|
|
start: start, |
|
|
@ -41,25 +41,26 @@ class Injector { |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Generates a solidity statement injection. Declared once per fn. |
|
|
|
* Generates a solidity statement injection. Declared once per fn. |
|
|
|
* Definition is the same for every fn in file. |
|
|
|
* Definition is the same for every fn in file. |
|
|
|
* @param {String} fileName |
|
|
|
* @param {String} id |
|
|
|
* @return {String} ex: bytes32[1] memory _sc_82e0891 |
|
|
|
* @return {String} ex: bytes32[1] memory _sc_82e0891 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
_getHashMethodDefinition(fileName){ |
|
|
|
_getHashMethodDefinition(id, contract){ |
|
|
|
const hash = web3Utils.keccak256(fileName).slice(0,10); |
|
|
|
const hash = web3Utils.keccak256(id).slice(0,10); |
|
|
|
const method = this._getMethodIdentifier(fileName); |
|
|
|
const method = this._getMethodIdentifier(id); |
|
|
|
return `\nfunction ${method}(bytes32 c__${hash}) public pure {}\n`; |
|
|
|
return `\nfunction ${method}(bytes32 c__${hash}) public pure {}\n`; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
injectLine(contract, fileName, injectionPoint, injection, instrumentation){ |
|
|
|
injectLine(contract, fileName, injectionPoint, injection, instrumentation){ |
|
|
|
const type = 'line'; |
|
|
|
const type = 'line'; |
|
|
|
const { start, end } = this._split(contract, injectionPoint); |
|
|
|
const { start, end } = this._split(contract, injectionPoint); |
|
|
|
|
|
|
|
const id = `${fileName}:${injection.contractName}`; |
|
|
|
|
|
|
|
|
|
|
|
const newLines = start.match(/\n/g); |
|
|
|
const newLines = start.match(/\n/g); |
|
|
|
const linecount = ( newLines || []).length + 1; |
|
|
|
const linecount = ( newLines || []).length + 1; |
|
|
|
contract.runnableLines.push(linecount); |
|
|
|
contract.runnableLines.push(linecount); |
|
|
|
|
|
|
|
|
|
|
|
const hash = this._getHash(fileName) |
|
|
|
const hash = this._getHash(id) |
|
|
|
const injectable = this._getInjectable(fileName, hash, type); |
|
|
|
const injectable = this._getInjectable(id, hash, type); |
|
|
|
|
|
|
|
|
|
|
|
instrumentation[hash] = { |
|
|
|
instrumentation[hash] = { |
|
|
|
id: linecount, |
|
|
|
id: linecount, |
|
|
@ -73,13 +74,14 @@ class Injector { |
|
|
|
|
|
|
|
|
|
|
|
injectStatement(contract, fileName, injectionPoint, injection, instrumentation) { |
|
|
|
injectStatement(contract, fileName, injectionPoint, injection, instrumentation) { |
|
|
|
const type = 'statement'; |
|
|
|
const type = 'statement'; |
|
|
|
|
|
|
|
const id = `${fileName}:${injection.contractName}`; |
|
|
|
|
|
|
|
|
|
|
|
const { |
|
|
|
const { |
|
|
|
start, |
|
|
|
start, |
|
|
|
end, |
|
|
|
end, |
|
|
|
hash, |
|
|
|
hash, |
|
|
|
injectable |
|
|
|
injectable |
|
|
|
} = this._getInjectionComponents(contract, injectionPoint, fileName, type); |
|
|
|
} = this._getInjectionComponents(contract, injectionPoint, id, type); |
|
|
|
|
|
|
|
|
|
|
|
instrumentation[hash] = { |
|
|
|
instrumentation[hash] = { |
|
|
|
id: injection.statementId, |
|
|
|
id: injection.statementId, |
|
|
@ -93,13 +95,14 @@ class Injector { |
|
|
|
|
|
|
|
|
|
|
|
injectFunction(contract, fileName, injectionPoint, injection, instrumentation){ |
|
|
|
injectFunction(contract, fileName, injectionPoint, injection, instrumentation){ |
|
|
|
const type = 'function'; |
|
|
|
const type = 'function'; |
|
|
|
|
|
|
|
const id = `${fileName}:${injection.contractName}`; |
|
|
|
|
|
|
|
|
|
|
|
const { |
|
|
|
const { |
|
|
|
start, |
|
|
|
start, |
|
|
|
end, |
|
|
|
end, |
|
|
|
hash, |
|
|
|
hash, |
|
|
|
injectable |
|
|
|
injectable |
|
|
|
} = this._getInjectionComponents(contract, injectionPoint, fileName, type); |
|
|
|
} = this._getInjectionComponents(contract, injectionPoint, id, type); |
|
|
|
|
|
|
|
|
|
|
|
instrumentation[hash] = { |
|
|
|
instrumentation[hash] = { |
|
|
|
id: injection.fnId, |
|
|
|
id: injection.fnId, |
|
|
@ -113,13 +116,14 @@ class Injector { |
|
|
|
|
|
|
|
|
|
|
|
injectBranch(contract, fileName, injectionPoint, injection, instrumentation){ |
|
|
|
injectBranch(contract, fileName, injectionPoint, injection, instrumentation){ |
|
|
|
const type = 'branch'; |
|
|
|
const type = 'branch'; |
|
|
|
|
|
|
|
const id = `${fileName}:${injection.contractName}`; |
|
|
|
|
|
|
|
|
|
|
|
const { |
|
|
|
const { |
|
|
|
start, |
|
|
|
start, |
|
|
|
end, |
|
|
|
end, |
|
|
|
hash, |
|
|
|
hash, |
|
|
|
injectable |
|
|
|
injectable |
|
|
|
} = this._getInjectionComponents(contract, injectionPoint, fileName, type); |
|
|
|
} = this._getInjectionComponents(contract, injectionPoint, id, type); |
|
|
|
|
|
|
|
|
|
|
|
instrumentation[hash] = { |
|
|
|
instrumentation[hash] = { |
|
|
|
id: injection.branchId, |
|
|
|
id: injection.branchId, |
|
|
@ -134,13 +138,14 @@ class Injector { |
|
|
|
|
|
|
|
|
|
|
|
injectEmptyBranch(contract, fileName, injectionPoint, injection, instrumentation) { |
|
|
|
injectEmptyBranch(contract, fileName, injectionPoint, injection, instrumentation) { |
|
|
|
const type = 'branch'; |
|
|
|
const type = 'branch'; |
|
|
|
|
|
|
|
const id = `${fileName}:${injection.contractName}`; |
|
|
|
|
|
|
|
|
|
|
|
const { |
|
|
|
const { |
|
|
|
start, |
|
|
|
start, |
|
|
|
end, |
|
|
|
end, |
|
|
|
hash, |
|
|
|
hash, |
|
|
|
injectable |
|
|
|
injectable |
|
|
|
} = this._getInjectionComponents(contract, injectionPoint, fileName, type); |
|
|
|
} = this._getInjectionComponents(contract, injectionPoint, id, type); |
|
|
|
|
|
|
|
|
|
|
|
instrumentation[hash] = { |
|
|
|
instrumentation[hash] = { |
|
|
|
id: injection.branchId, |
|
|
|
id: injection.branchId, |
|
|
@ -155,13 +160,14 @@ class Injector { |
|
|
|
|
|
|
|
|
|
|
|
injectAssertPre(contract, fileName, injectionPoint, injection, instrumentation) { |
|
|
|
injectAssertPre(contract, fileName, injectionPoint, injection, instrumentation) { |
|
|
|
const type = 'assertPre'; |
|
|
|
const type = 'assertPre'; |
|
|
|
|
|
|
|
const id = `${fileName}:${injection.contractName}`; |
|
|
|
|
|
|
|
|
|
|
|
const { |
|
|
|
const { |
|
|
|
start, |
|
|
|
start, |
|
|
|
end, |
|
|
|
end, |
|
|
|
hash, |
|
|
|
hash, |
|
|
|
injectable |
|
|
|
injectable |
|
|
|
} = this._getInjectionComponents(contract, injectionPoint, fileName, type); |
|
|
|
} = this._getInjectionComponents(contract, injectionPoint, id, type); |
|
|
|
|
|
|
|
|
|
|
|
instrumentation[hash] = { |
|
|
|
instrumentation[hash] = { |
|
|
|
id: injection.branchId, |
|
|
|
id: injection.branchId, |
|
|
@ -175,13 +181,14 @@ class Injector { |
|
|
|
|
|
|
|
|
|
|
|
injectAssertPost(contract, fileName, injectionPoint, injection, instrumentation) { |
|
|
|
injectAssertPost(contract, fileName, injectionPoint, injection, instrumentation) { |
|
|
|
const type = 'assertPost'; |
|
|
|
const type = 'assertPost'; |
|
|
|
|
|
|
|
const id = `${fileName}:${injection.contractName}`; |
|
|
|
|
|
|
|
|
|
|
|
const { |
|
|
|
const { |
|
|
|
start, |
|
|
|
start, |
|
|
|
end, |
|
|
|
end, |
|
|
|
hash, |
|
|
|
hash, |
|
|
|
injectable |
|
|
|
injectable |
|
|
|
} = this._getInjectionComponents(contract, injectionPoint, fileName, type); |
|
|
|
} = this._getInjectionComponents(contract, injectionPoint, id, type); |
|
|
|
|
|
|
|
|
|
|
|
instrumentation[hash] = { |
|
|
|
instrumentation[hash] = { |
|
|
|
id: injection.branchId, |
|
|
|
id: injection.branchId, |
|
|
@ -196,7 +203,8 @@ class Injector { |
|
|
|
injectHashMethod(contract, fileName, injectionPoint, injection, instrumentation){ |
|
|
|
injectHashMethod(contract, fileName, injectionPoint, injection, instrumentation){ |
|
|
|
const start = contract.instrumented.slice(0, injectionPoint); |
|
|
|
const start = contract.instrumented.slice(0, injectionPoint); |
|
|
|
const end = contract.instrumented.slice(injectionPoint); |
|
|
|
const end = contract.instrumented.slice(injectionPoint); |
|
|
|
contract.instrumented = `${start}${this._getHashMethodDefinition(fileName)}${end}`; |
|
|
|
const id = `${fileName}:${injection.contractName}`; |
|
|
|
|
|
|
|
contract.instrumented = `${start}${this._getHashMethodDefinition(id)}${end}`; |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|