Merge pull request #4583 from ethereum/nested_array_library_changelog

Bugfix Changelog entry regarding nested arrays returned by library functions
This commit is contained in:
chriseth 2018-08-15 12:30:54 +02:00 committed by GitHub
commit c7d2af2637
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 187 additions and 4 deletions

View File

@ -179,6 +179,17 @@ jobs:
name: Check spelling
command: ~/.local/bin/codespell -S "*.enc,.git" -I ./scripts/codespell_whitelist.txt
test_buglist:
docker:
- image: circleci/node
environment:
TERM: xterm
steps:
- checkout
- run:
name: Test buglist
command: ./test/buglistTests.js
test_x86_linux:
docker:
- image: buildpack-deps:artful
@ -252,6 +263,7 @@ workflows:
build_all:
jobs:
- test_check_spelling: *build_on_tags
- test_buglist: *build_on_tags
- build_emscripten: *build_on_tags
- test_emscripten_solcjs:
<<: *build_on_tags

View File

@ -1,4 +1,13 @@
[
{
"name": "NestedArrayFunctionCallDecoder",
"summary": "Calling functions that return multi-dimensional fixed-size arrays can result in memory corruption.",
"description": "If Solidity code calls a function that returns a multi-dimensional fixed-size array, array elements are incorrectly interpreted as memory pointers and thus can cause memory corruption if the return values are accessed. Calling functions with multi-dimensional fixed-size arrays is unaffected as is returning fixed-size arrays from function calls. The regular expression only checks if such functions are present, not if they are called, which is required for the contract to be affected.",
"introduced": "0.1.4",
"fixed": "0.4.22",
"severity": "medium",
"check": {"regex-source": "returns[^;{]*\\[\\s*[^\\] \\t\\r\\n\\v\\f][^\\]]*\\]\\s*\\[\\s*[^\\] \\t\\r\\n\\v\\f][^\\]]*\\][^{;]*[;{]"}
},
{
"name": "OneOfTwoConstructorsSkipped",
"summary": "If a contract has both a new-style constructor (using the constructor keyword) and an old-style constructor (a function with the same name as the contract) at the same time, one of them will be ignored.",

View File

@ -56,6 +56,14 @@ conditions
is an object that can contain a boolean value ``optimizer``, which
means that the optimizer has to be switched on to enable the bug.
If no conditions are given, assume that the bug is present.
check
This field contains JavaScript regular expressions that are to be matched
against the source code ("source-regex") to find out if the
smart contract contains the bug or not. If there is no match,
then the bug is very likely not present. If there is a match,
the bug might be present. For improved accuracy, the regular
expression should be applied to the source code after stripping
comments.
.. literalinclude:: bugs.json
:language: js

View File

@ -69,6 +69,7 @@
},
"0.1.4": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"ECRecoverMalformedInput",
"SkipEmptyStringLiteral",
@ -86,6 +87,7 @@
},
"0.1.5": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"ECRecoverMalformedInput",
"SkipEmptyStringLiteral",
@ -103,6 +105,7 @@
},
"0.1.6": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"ECRecoverMalformedInput",
"SkipEmptyStringLiteral",
@ -121,6 +124,7 @@
},
"0.1.7": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"ECRecoverMalformedInput",
"SkipEmptyStringLiteral",
@ -139,6 +143,7 @@
},
"0.2.0": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"ECRecoverMalformedInput",
"SkipEmptyStringLiteral",
@ -157,6 +162,7 @@
},
"0.2.1": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"ECRecoverMalformedInput",
"SkipEmptyStringLiteral",
@ -175,6 +181,7 @@
},
"0.2.2": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"ECRecoverMalformedInput",
"SkipEmptyStringLiteral",
@ -193,6 +200,7 @@
},
"0.3.0": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
"ECRecoverMalformedInput",
@ -211,6 +219,7 @@
},
"0.3.1": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
"ECRecoverMalformedInput",
@ -228,6 +237,7 @@
},
"0.3.2": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
"ECRecoverMalformedInput",
@ -245,6 +255,7 @@
},
"0.3.3": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
"ECRecoverMalformedInput",
@ -261,6 +272,7 @@
},
"0.3.4": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
"ECRecoverMalformedInput",
@ -277,6 +289,7 @@
},
"0.3.5": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
"ECRecoverMalformedInput",
@ -293,6 +306,7 @@
},
"0.3.6": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
"ECRecoverMalformedInput",
@ -307,6 +321,7 @@
},
"0.4.0": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
"ECRecoverMalformedInput",
@ -321,6 +336,7 @@
},
"0.4.1": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
"ECRecoverMalformedInput",
@ -335,6 +351,7 @@
},
"0.4.10": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
"ECRecoverMalformedInput",
@ -345,6 +362,7 @@
},
"0.4.11": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
"ECRecoverMalformedInput",
@ -354,6 +372,7 @@
},
"0.4.12": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
"ECRecoverMalformedInput"
@ -362,6 +381,7 @@
},
"0.4.13": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
"ECRecoverMalformedInput"
@ -370,6 +390,7 @@
},
"0.4.14": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue"
],
@ -377,32 +398,40 @@
},
"0.4.15": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector"
],
"released": "2017-08-08"
},
"0.4.16": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector"
],
"released": "2017-08-24"
},
"0.4.17": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector"
],
"released": "2017-09-21"
},
"0.4.18": {
"bugs": [],
"bugs": [
"NestedArrayFunctionCallDecoder"
],
"released": "2017-10-18"
},
"0.4.19": {
"bugs": [],
"bugs": [
"NestedArrayFunctionCallDecoder"
],
"released": "2017-11-30"
},
"0.4.2": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
"ECRecoverMalformedInput",
@ -415,11 +444,15 @@
"released": "2016-09-17"
},
"0.4.20": {
"bugs": [],
"bugs": [
"NestedArrayFunctionCallDecoder"
],
"released": "2018-02-14"
},
"0.4.21": {
"bugs": [],
"bugs": [
"NestedArrayFunctionCallDecoder"
],
"released": "2018-03-07"
},
"0.4.22": {
@ -438,6 +471,7 @@
},
"0.4.3": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
"ECRecoverMalformedInput",
@ -450,6 +484,7 @@
},
"0.4.4": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
"ECRecoverMalformedInput",
@ -461,6 +496,7 @@
},
"0.4.5": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
"ECRecoverMalformedInput",
@ -473,6 +509,7 @@
},
"0.4.6": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
"ECRecoverMalformedInput",
@ -484,6 +521,7 @@
},
"0.4.7": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
"ECRecoverMalformedInput",
@ -494,6 +532,7 @@
},
"0.4.8": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
"ECRecoverMalformedInput",
@ -504,6 +543,7 @@
},
"0.4.9": {
"bugs": [
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
"ECRecoverMalformedInput",

45
test/buglistTests.js Executable file
View File

@ -0,0 +1,45 @@
#!/usr/bin/env node
"use strict";
var fs = require('fs')
var bugs = JSON.parse(fs.readFileSync(__dirname + '/../docs/bugs.json', 'utf8'))
var bugsByName = {}
for (var i in bugs)
{
if (bugs[i].name in bugsByName)
{
throw "Duplicate bug name: " + bugs[i].name
}
bugsByName[bugs[i].name] = bugs[i]
}
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)
{
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]
}
}
}

View File

@ -0,0 +1,69 @@
# NestedArrayFunctionCallDecoder
## buggy
function f() pure returns (uint[2][2]) { }
--
function f() returns (uint[2][2] a) { }
--
function f() returns (uint x, uint[200][2] a) { }
--
function f() returns (uint[200][2] a, uint x) { }
--
function f() returns (uint[200][2] a, uint x);
--
function f() returns (
uint
[
200
]
[2]
a, uint x);
--
function f() returns (
uint
[
ContractName.ConstantName
]
[2]
a, uint x);
## fine
function f() returns (uint[2]) { }
--
function f() public pure returns (uint[2][] a) { }
--
function f() public pure returns (uint[ 2 ] [ ] a) { }
--
function f() public pure returns (uint x, uint[] a) { }
--
function f(uint[2][2]) { }
--
function f() m(uint[2][2]) { }
--
function f() returns (uint, uint) { uint[2][2] memory x; }