Fix solidity var extraction. was using the type property. now using stateVariable && storageLocation

pull/3094/head
yann300 7 years ago
parent 2fd05abe4b
commit 42d1d57a46
  1. 7
      remix-solidity/src/decoder/decodeInfo.js
  2. 9
      remix-solidity/src/decoder/internalCallTree.js
  3. 2
      remix-solidity/src/decoder/stateDecoder.js
  4. 13
      remix-solidity/src/decoder/types/util.js
  5. 41
      remix-solidity/test/decoder/decodeInfo.js

@ -190,7 +190,7 @@ function struct (type, stateDefinitions, contractName, location) {
if (!location) {
location = match[2].trim()
}
var memberDetails = getStructMembers(match[1], stateDefinitions, contractName) // type is used to extract the ast struct definition
var memberDetails = getStructMembers(match[1], stateDefinitions, contractName, location) // type is used to extract the ast struct definition
if (!memberDetails) return null
return new StructType(memberDetails, location, match[1])
} else {
@ -230,9 +230,10 @@ function getEnum (type, stateDefinitions, contractName) {
* @param {String} typeName - name of the struct type (e.g struct <name>)
* @param {Object} stateDefinitions - all state definition given by the AST (including struct and enum type declaration) for all contracts
* @param {String} contractName - contract the @args typeName belongs to
* @param {String} location - location of the data (storage ref| storage pointer| memory| calldata)
* @return {Array} containing all members of the current struct type
*/
function getStructMembers (type, stateDefinitions, contractName) {
function getStructMembers (type, stateDefinitions, contractName, location) {
var split = type.split('.')
if (!split.length) {
type = contractName + '.' + type
@ -243,7 +244,7 @@ function getStructMembers (type, stateDefinitions, contractName) {
if (state) {
for (var dec of state.stateDefinitions) {
if (dec.name === 'StructDefinition' && type === contractName + '.' + dec.attributes.name) {
var offsets = computeOffsets(dec.children, stateDefinitions, contractName)
var offsets = computeOffsets(dec.children, stateDefinitions, contractName, location)
if (!offsets) {
return null
}

@ -6,6 +6,7 @@ var EventManager = remixLib.EventManager
var decodeInfo = require('./decodeInfo')
var util = remixLib.util
var traceHelper = remixLib.helpers.trace
var typesUtil = require('./types/util.js')
/**
* Tree representing internal jump into function.
@ -189,9 +190,11 @@ function includeVariableDeclaration (tree, step, sourceLocation, scopeId, newLoc
tree.solidityProxy.contractNameAt(step, (error, contractName) => { // cached
if (!error) {
var states = tree.solidityProxy.extractStatesDefinitions()
var location = typesUtil.extractLocationFromAstVariable(variableDeclaration)
location = location === 'default' ? 'storage' : location
tree.scopes[scopeId].locals[variableDeclaration.attributes.name] = {
name: variableDeclaration.attributes.name,
type: decodeInfo.parseType(variableDeclaration.attributes.type, states, contractName),
type: decodeInfo.parseType(variableDeclaration.attributes.type, states, contractName, location),
stackDepth: stack.length,
sourceLocation: sourceLocation
}
@ -274,9 +277,11 @@ function addParams (parameterList, tree, scopeId, states, contractName, sourceLo
var param = parameterList.children[inputParam]
var stackDepth = stackLength + (dir * stackPosition)
if (stackDepth >= 0) {
var location = typesUtil.extractLocationFromAstVariable(param)
location = location === 'default' ? 'memory' : location
tree.scopes[scopeId].locals[param.attributes.name] = {
name: param.attributes.name,
type: decodeInfo.parseType(param.attributes.type, states, contractName),
type: decodeInfo.parseType(param.attributes.type, states, contractName, location),
stackDepth: stackDepth,
sourceLocation: sourceLocation
}

@ -40,7 +40,7 @@ function extractStateVariables (contractName, sourcesList) {
return []
}
var types = states[contractName].stateVariables
var offsets = decodeInfo.computeOffsets(types, states, contractName)
var offsets = decodeInfo.computeOffsets(types, states, contractName, 'storage')
if (!offsets) {
return [] // TODO should maybe return an error
}

@ -11,7 +11,8 @@ module.exports = {
add: add,
extractLocation: extractLocation,
removeLocation: removeLocation,
normalizeHex: normalizeHex
normalizeHex: normalizeHex,
extractLocationFromAstVariable: extractLocationFromAstVariable
}
function decodeIntFromHex (value, byteLength, signed) {
@ -100,6 +101,16 @@ function extractLocation (type) {
}
}
function extractLocationFromAstVariable (node) {
if (node.attributes.storageLocation !== 'default') {
return node.attributes.storageLocation
} else if (node.attributes.stateVariable) {
return 'storage'
} else {
return 'default' // local variables => storage, function parameters & return values => memory, state => storage
}
}
function normalizeHex (hex) {
hex = hex.replace('0x', '')
if (hex.length < 64) {

@ -8,6 +8,7 @@ var contracts = require('./contracts/miscContracts')
var simplecontracts = require('./contracts/simpleContract')
var remixLib = require('remix-lib')
var compilerInput = remixLib.helpers.compiler.compilerInput
var util = require('../../src/decoder/types/util')
tape('solidity', function (t) {
t.test('astHelper, decodeInfo', function (st) {
@ -17,31 +18,31 @@ tape('solidity', function (t) {
var state = astHelper.extractStateDefinitions('test.sol:contractUint', output.sources)
var states = astHelper.extractStatesDefinitions(output.sources)
var stateDef = state.stateDefinitions
var parsedType = decodeInfo.parseType(stateDef[0].attributes.type, states, 'contractUint')
var parsedType = decodeInfo.parseType(stateDef[0].attributes.type, states, 'contractUint', util.extractLocationFromAstVariable(stateDef[0]))
checkDecodeInfo(st, parsedType, 1, 1, 'uint8')
parsedType = decodeInfo.parseType(stateDef[2].attributes.type, states, 'contractUint')
parsedType = decodeInfo.parseType(stateDef[2].attributes.type, states, 'contractUint', util.extractLocationFromAstVariable(stateDef[2]))
checkDecodeInfo(st, parsedType, 1, 32, 'uint256')
parsedType = decodeInfo.parseType(stateDef[3].attributes.type, states, 'contractUint')
parsedType = decodeInfo.parseType(stateDef[3].attributes.type, states, 'contractUint', util.extractLocationFromAstVariable(stateDef[3]))
checkDecodeInfo(st, parsedType, 1, 32, 'uint256')
parsedType = decodeInfo.parseType(stateDef[4].attributes.type, states, 'contractUint')
parsedType = decodeInfo.parseType(stateDef[4].attributes.type, states, 'contractUint', util.extractLocationFromAstVariable(stateDef[4]))
checkDecodeInfo(st, parsedType, 1, 16, 'bytes16')
state = astHelper.extractStateDefinitions('test.sol:contractStructAndArray', output.sources)
stateDef = state.stateDefinitions
parsedType = decodeInfo.parseType(stateDef[1].attributes.type, states, 'contractStructAndArray')
parsedType = decodeInfo.parseType(stateDef[1].attributes.type, states, 'contractStructAndArray', util.extractLocationFromAstVariable(stateDef[1]))
checkDecodeInfo(st, parsedType, 2, 32, 'struct contractStructAndArray.structDef')
parsedType = decodeInfo.parseType(stateDef[2].attributes.type, states, 'contractStructAndArray')
parsedType = decodeInfo.parseType(stateDef[2].attributes.type, states, 'contractStructAndArray', util.extractLocationFromAstVariable(stateDef[2]))
checkDecodeInfo(st, parsedType, 6, 32, 'struct contractStructAndArray.structDef[3]')
parsedType = decodeInfo.parseType(stateDef[3].attributes.type, states, 'contractStructAndArray')
parsedType = decodeInfo.parseType(stateDef[3].attributes.type, states, 'contractStructAndArray', util.extractLocationFromAstVariable(stateDef[3]))
checkDecodeInfo(st, parsedType, 2, 32, 'bytes12[4]')
state = astHelper.extractStateDefinitions('test.sol:contractArray', output.sources)
stateDef = state.stateDefinitions
parsedType = decodeInfo.parseType(stateDef[0].attributes.type, states, 'contractArray')
parsedType = decodeInfo.parseType(stateDef[0].attributes.type, states, 'contractArray', util.extractLocationFromAstVariable(stateDef[0]))
checkDecodeInfo(st, parsedType, 1, 32, 'uint32[5]')
parsedType = decodeInfo.parseType(stateDef[1].attributes.type, states, 'contractArray')
parsedType = decodeInfo.parseType(stateDef[1].attributes.type, states, 'contractArray', util.extractLocationFromAstVariable(stateDef[1]))
checkDecodeInfo(st, parsedType, 1, 32, 'int8[]')
parsedType = decodeInfo.parseType(stateDef[2].attributes.type, states, 'contractArray')
parsedType = decodeInfo.parseType(stateDef[2].attributes.type, states, 'contractArray', util.extractLocationFromAstVariable(stateDef[2]))
checkDecodeInfo(st, parsedType, 4, 32, 'int16[][3][][4]')
state = astHelper.extractStateDefinitions('test.sol:contractEnum', output.sources)
@ -51,17 +52,17 @@ tape('solidity', function (t) {
state = astHelper.extractStateDefinitions('test.sol:contractSmallVariable', output.sources)
stateDef = state.stateDefinitions
parsedType = decodeInfo.parseType(stateDef[0].attributes.type, states, 'contractSmallVariable')
parsedType = decodeInfo.parseType(stateDef[0].attributes.type, states, 'contractSmallVariable', util.extractLocationFromAstVariable(stateDef[0]))
checkDecodeInfo(st, parsedType, 1, 1, 'int8')
parsedType = decodeInfo.parseType(stateDef[1].attributes.type, states, 'contractSmallVariable')
parsedType = decodeInfo.parseType(stateDef[1].attributes.type, states, 'contractSmallVariable', util.extractLocationFromAstVariable(stateDef[1]))
checkDecodeInfo(st, parsedType, 1, 1, 'uint8')
parsedType = decodeInfo.parseType(stateDef[2].attributes.type, states, 'contractSmallVariable')
parsedType = decodeInfo.parseType(stateDef[2].attributes.type, states, 'contractSmallVariable', util.extractLocationFromAstVariable(stateDef[2]))
checkDecodeInfo(st, parsedType, 1, 2, 'uint16')
parsedType = decodeInfo.parseType(stateDef[3].attributes.type, states, 'contractSmallVariable')
parsedType = decodeInfo.parseType(stateDef[3].attributes.type, states, 'contractSmallVariable', util.extractLocationFromAstVariable(stateDef[3]))
checkDecodeInfo(st, parsedType, 1, 4, 'int32')
parsedType = decodeInfo.parseType(stateDef[4].attributes.type, states, 'contractSmallVariable')
parsedType = decodeInfo.parseType(stateDef[4].attributes.type, states, 'contractSmallVariable', util.extractLocationFromAstVariable(stateDef[4]))
checkDecodeInfo(st, parsedType, 1, 32, 'uint256')
parsedType = decodeInfo.parseType(stateDef[5].attributes.type, states, 'contractSmallVariable')
parsedType = decodeInfo.parseType(stateDef[5].attributes.type, states, 'contractSmallVariable', util.extractLocationFromAstVariable(stateDef[5]))
checkDecodeInfo(st, parsedType, 1, 2, 'int16')
output = compiler.compileStandardWrapper(compilerInput(simplecontracts))
@ -70,16 +71,16 @@ tape('solidity', function (t) {
state = astHelper.extractStateDefinitions('test.sol:simpleContract', output.sources)
states = astHelper.extractStatesDefinitions(output.sources)
stateDef = state.stateDefinitions
parsedType = decodeInfo.parseType(stateDef[2].attributes.type, states, 'simpleContract')
parsedType = decodeInfo.parseType(stateDef[2].attributes.type, states, 'simpleContract', util.extractLocationFromAstVariable(stateDef[2]))
checkDecodeInfo(st, parsedType, 2, 32, 'struct simpleContract.structDef')
parsedType = decodeInfo.parseType(stateDef[3].attributes.type, states, 'simpleContract')
parsedType = decodeInfo.parseType(stateDef[3].attributes.type, states, 'simpleContract', util.extractLocationFromAstVariable(stateDef[3]))
checkDecodeInfo(st, parsedType, 6, 32, 'struct simpleContract.structDef[3]')
parsedType = decodeInfo.parseType(stateDef[4].attributes.type, states, 'simpleContract')
parsedType = decodeInfo.parseType(stateDef[4].attributes.type, states, 'simpleContract', util.extractLocationFromAstVariable(stateDef[4]))
checkDecodeInfo(st, parsedType, 1, 1, 'enum')
state = astHelper.extractStateDefinitions('test.sol:test2', output.sources)
stateDef = state.stateDefinitions
parsedType = decodeInfo.parseType(stateDef[0].attributes.type, states, 'test1')
parsedType = decodeInfo.parseType(stateDef[0].attributes.type, states, 'test1', util.extractLocationFromAstVariable(stateDef[0]))
checkDecodeInfo(st, parsedType, 0, 32, 'struct test1.str')
state = stateDecoder.extractStateVariables('test.sol:test2', output.sources)

Loading…
Cancel
Save