From 9927964d218ac234e50c1818be655d92b3b2887b Mon Sep 17 00:00:00 2001 From: Leonardo Alt Date: Tue, 21 Aug 2018 16:09:53 +0200 Subject: Buglist check script supports json paths --- test/buglistTests.js | 131 ++++++++++++++++++++++++++++++++++++------- test/buglist_test_vectors.md | 45 +++++++++++++++ 2 files changed, 155 insertions(+), 21 deletions(-) (limited to 'test') diff --git a/test/buglistTests.js b/test/buglistTests.js index 6b7df2f2..f24f0cb6 100755 --- a/test/buglistTests.js +++ b/test/buglistTests.js @@ -2,6 +2,11 @@ "use strict"; +var util = require('util') +var exec = util.promisify(require('child_process').exec) +var mktemp = require('mktemp'); +var download = require('download') +var JSONPath = require('JSONPath') var fs = require('fs') var bugs = JSON.parse(fs.readFileSync(__dirname + '/../docs/bugs.json', 'utf8')) @@ -19,27 +24,111 @@ var tests = fs.readFileSync(__dirname + '/buglist_test_vectors.md', 'utf8') var testVectorParser = /\s*#\s+(\S+)\s+## buggy\n([^#]*)## fine\n([^#]*)/g -var result; -while ((result = testVectorParser.exec(tests)) !== null) +runTests() + +async function runTests() { - var name = result[1] - var buggy = result[2].split('\n--\n') - var fine = result[3].split('\n--\n') - console.log("Testing " + name + " with " + buggy.length + " buggy and " + fine.length + " fine instances") + var result; + while ((result = testVectorParser.exec(tests)) !== null) + { + var name = result[1] + var buggy = result[2].split('\n--\n') + var fine = result[3].split('\n--\n') + console.log("Testing " + name + " with " + buggy.length + " buggy and " + fine.length + " fine instances") - var regex = RegExp(bugsByName[name].check['regex-source']) - for (var i in buggy) - { - if (!regex.exec(buggy[i])) - { - throw "Bug " + name + ": Buggy source does not match: " + buggy[i] - } - } - for (var i in fine) - { - if (regex.exec(fine[i])) - { - throw "Bug " + name + ": Non-buggy source matches: " + fine[i] - } - } + try { + await checkRegex(name, buggy, fine) + await checkJSONPath(name, buggy, fine) + } catch (err) { + console.error("Error: " + err) + } + } +} + +function checkRegex(name, buggy, fine) +{ + return new Promise(function(resolve, reject) { + var regexStr = bugsByName[name].check['regex-source'] + if (regexStr !== undefined) + { + var regex = RegExp(regexStr) + for (var i in buggy) + { + if (!regex.exec(buggy[i])) + { + reject("Bug " + name + ": Buggy source does not match: " + buggy[i]) + } + } + for (var i in fine) + { + if (regex.exec(fine[i])) + { + reject("Bug " + name + ": Non-buggy source matches: " + fine[i]) + } + } + } + resolve() + }) +} + +async function checkJSONPath(name, buggy, fine) +{ + var jsonPath = bugsByName[name].check['ast-compact-json-path'] + if (jsonPath !== undefined) + { + var url = "http://github.com/ethereum/solidity/releases/download/v" + bugsByName[name].introduced + "/solc-static-linux" + try { + var tmpdir = await mktemp.createDir('XXXXX') + var binary = tmpdir + "/solc-static-linux" + await download(url, tmpdir) + exec("chmod +x " + binary) + for (var i in buggy) + { + var result = await checkJsonPathTest(buggy[i], tmpdir, binary, jsonPath, i) + if (!result) + throw "Bug " + name + ": Buggy source does not contain path: " + buggy[i] + } + for (var i in fine) + { + var result = await checkJsonPathTest(fine[i], tmpdir, binary, jsonPath, i + buggy.length) + if (result) + throw "Bug " + name + ": Non-buggy source contains path: " + fine[i] + } + exec("rm -r " + tmpdir) + } catch (err) { + throw err + } + } +} + +function checkJsonPathTest(code, tmpdir, binary, query, idx) { + return new Promise(function(resolve, reject) { + var solFile = tmpdir + "/jsonPath" + idx + ".sol" + var astFile = tmpdir + "/ast" + idx + ".json" + writeFilePromise(solFile, code) + .then(() => { + return exec(binary + " --ast-compact-json " + solFile + " > " + astFile) + }) + .then(() => { + var jsonRE = /(\{[\s\S]*\})/ + var ast = JSON.parse(jsonRE.exec(fs.readFileSync(astFile, 'utf8'))[0]) + var result = JSONPath({json: ast, path: query}) + if (result.length > 0) + resolve(true) + else + resolve(false) + }) + .catch((err) => { + reject(err) + }) + }) +} + +function writeFilePromise(filename, data) { + return new Promise(function(resolve, reject) { + fs.writeFile(filename, data, 'utf8', function(err) { + if (err) reject(err) + else resolve(data) + }) + }) } diff --git a/test/buglist_test_vectors.md b/test/buglist_test_vectors.md index ce95403b..f15cf151 100644 --- a/test/buglist_test_vectors.md +++ b/test/buglist_test_vectors.md @@ -67,3 +67,48 @@ function f() m(uint[2][2]) { } -- function f() returns (uint, uint) { uint[2][2] memory x; } + +# EventStructWrongData + +## buggy + +pragma experimental ABIEncoderV2; +contract C +{ + struct S { uint x; } + event E(S); + event F(S); + enum A { B, C } + event G(A); + function f(S s); +} + +-- + +pragma experimental ABIEncoderV2; +contract C +{ + struct S { uint x; } + event E(S indexed); + event F(uint, S, bool); +} + +## fine + +pragma experimental ABIEncoderV2; +contract C +{ + struct S { uint x; } + enum A { B, C } + event G(A); +} + +-- + +pragma experimental ABIEncoderV2; +contract C +{ + struct S { uint x; } + function f(S s); + S s1; +} -- cgit v1.2.3