aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/conf.py2
-rw-r--r--docs/control-structures.rst4
-rw-r--r--docs/miscellaneous.rst2
-rw-r--r--docs/security-considerations.rst6
-rw-r--r--libsolidity/interface/CompilerStack.cpp6
-rw-r--r--libsolidity/interface/CompilerStack.h3
-rw-r--r--solc/CommandLineInterface.cpp16
-rw-r--r--solc/jsonCompiler.cpp16
8 files changed, 39 insertions, 16 deletions
diff --git a/docs/conf.py b/docs/conf.py
index 8776ec43..d0e26362 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -49,7 +49,7 @@ master_doc = 'index'
# General information about the project.
project = 'Solidity'
-copyright = '2015, Ethereum'
+copyright = '2016, Ethereum'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
diff --git a/docs/control-structures.rst b/docs/control-structures.rst
index 064996ac..f30a5bdd 100644
--- a/docs/control-structures.rst
+++ b/docs/control-structures.rst
@@ -422,7 +422,7 @@ The opcodes ``pushi`` and ``jumpdest`` cannot be used directly.
+-------------------------+------+-----------------------------------------------------------------+
| dup1 ... dup16 | | copy ith stack slot to the top (counting from top) |
+-------------------------+------+-----------------------------------------------------------------+
-| swap1 ... swap1 | `*` | swap topmost and ith stack slot below it |
+| swap1 ... swap16 | `*` | swap topmost and ith stack slot below it |
+-------------------------+------+-----------------------------------------------------------------+
| mload(p) | | mem[p..(p+32)) |
+-------------------------+------+-----------------------------------------------------------------+
@@ -661,7 +661,7 @@ variables. Take care that when you assign to variables that point to
memory or storage, you will only change the pointer and not the data.
There are two kinds of assignments: Functional-style and instruction-style.
-For functionaly-style assignments (``variable := value``), you need to provide a value in a
+For functional-style assignments (``variable := value``), you need to provide a value in a
functional-style expression that results in exactly one stack value
and for instruction-style (``=: variable``), the value is just taken from the stack top.
For both ways, the colon points to the name of the variable.
diff --git a/docs/miscellaneous.rst b/docs/miscellaneous.rst
index 85fc286c..825be2ce 100644
--- a/docs/miscellaneous.rst
+++ b/docs/miscellaneous.rst
@@ -192,7 +192,7 @@ Function Visibility Specifiers
- ``public``: visible externally and internally (creates accessor function for storage/state variables)
- ``private``: only visible in the current contract
-- ``external``: only visible externally (only for functions) - i.e. can only be message-called (via ``this.fun``)
+- ``external``: only visible externally (only for functions) - i.e. can only be message-called (via ``this.func``)
- ``internal``: only visible internally
diff --git a/docs/security-considerations.rst b/docs/security-considerations.rst
index f1a5dc03..87ee567d 100644
--- a/docs/security-considerations.rst
+++ b/docs/security-considerations.rst
@@ -146,7 +146,11 @@ Minor Details
Furthermore, it is not enforced by the EVM, so a contract function that "claims"
to be constant might still cause changes to the state.
- Types that do not occupy the full 32 bytes might contain "dirty higher order bits".
- This is especially important if you access ``msg.data`` - it poses a malleability risk.
+ This is especially important if you access ``msg.data`` - it poses a malleability risk:
+ You can craft transactions that call a function ``f(uint8 x)`` with a raw byte argument
+ of ``0xff000001`` and with ``0x00000001``. Both are fed to the contract and both will
+ look like the number ``1`` as far as ``x`` is concerned, but ``msg.data`` will
+ be different, so if you use ``sha3(msg.data)`` for anything, you will get different results.
***************
Recommendations
diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp
index c28e926b..4776a4ce 100644
--- a/libsolidity/interface/CompilerStack.cpp
+++ b/libsolidity/interface/CompilerStack.cpp
@@ -253,9 +253,11 @@ void CompilerStack::link(const std::map<string, h160>& _libraries)
}
}
-bool CompilerStack::prepareFormalAnalysis()
+bool CompilerStack::prepareFormalAnalysis(ErrorList* _errors)
{
- Why3Translator translator(m_errors);
+ if (!_errors)
+ _errors = &m_errors;
+ Why3Translator translator(*_errors);
for (Source const* source: m_sourceOrder)
if (!translator.process(*source->ast))
return false;
diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h
index e111c982..9d2aace4 100644
--- a/libsolidity/interface/CompilerStack.h
+++ b/libsolidity/interface/CompilerStack.h
@@ -124,8 +124,9 @@ public:
void link(std::map<std::string, h160> const& _libraries);
/// Tries to translate all source files into a language suitable for formal analysis.
+ /// @param _errors list to store errors - defaults to the internal error list.
/// @returns false on error.
- bool prepareFormalAnalysis();
+ bool prepareFormalAnalysis(ErrorList* _errors = nullptr);
std::string const& formalTranslation() const { return m_formalTranslation; }
/// @returns the assembled object for a contract.
diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp
index 17ab5ba4..09c7c8e8 100644
--- a/solc/CommandLineInterface.cpp
+++ b/solc/CommandLineInterface.cpp
@@ -531,17 +531,17 @@ bool CommandLineInterface::processInput()
CompilerStack::ReadFileCallback fileReader = [this](string const& _path)
{
- auto boostPath = boost::filesystem::path(_path);
- if (!boost::filesystem::exists(boostPath))
+ auto path = boost::filesystem::path(_path);
+ if (!boost::filesystem::exists(path))
return CompilerStack::ReadFileResult{false, "File not found."};
- boostPath = boost::filesystem::canonical(boostPath);
+ auto canonicalPath = boost::filesystem::canonical(path);
bool isAllowed = false;
for (auto const& allowedDir: m_allowedDirectories)
{
// If dir is a prefix of boostPath, we are fine.
if (
- std::distance(allowedDir.begin(), allowedDir.end()) <= std::distance(boostPath.begin(), boostPath.end()) &&
- std::equal(allowedDir.begin(), allowedDir.end(), boostPath.begin())
+ std::distance(allowedDir.begin(), allowedDir.end()) <= std::distance(canonicalPath.begin(), canonicalPath.end()) &&
+ std::equal(allowedDir.begin(), allowedDir.end(), canonicalPath.begin())
)
{
isAllowed = true;
@@ -550,12 +550,12 @@ bool CommandLineInterface::processInput()
}
if (!isAllowed)
return CompilerStack::ReadFileResult{false, "File outside of allowed directories."};
- else if (!boost::filesystem::is_regular_file(boostPath))
+ else if (!boost::filesystem::is_regular_file(canonicalPath))
return CompilerStack::ReadFileResult{false, "Not a valid file."};
else
{
- auto contents = dev::contentsString(boostPath.string());
- m_sourceCodes[boostPath.string()] = contents;
+ auto contents = dev::contentsString(canonicalPath.string());
+ m_sourceCodes[path.string()] = contents;
return CompilerStack::ReadFileResult{true, contents};
}
};
diff --git a/solc/jsonCompiler.cpp b/solc/jsonCompiler.cpp
index e8f674a0..bc1305c5 100644
--- a/solc/jsonCompiler.cpp
+++ b/solc/jsonCompiler.cpp
@@ -219,6 +219,22 @@ string compile(StringMap const& _sources, bool _optimize, CStyleReadFileCallback
output["contracts"][contractName] = contractData;
}
+ // Do not taint the internal error list
+ ErrorList formalErrors;
+ if (compiler.prepareFormalAnalysis(&formalErrors))
+ output["formal"]["why3"] = compiler.formalTranslation();
+ if (!formalErrors.empty())
+ {
+ Json::Value errors(Json::arrayValue);
+ for (auto const& error: formalErrors)
+ errors.append(formatError(
+ *error,
+ (error->type() == Error::Type::Warning) ? "Warning" : "Error",
+ scannerFromSourceName
+ ));
+ output["formal"]["errors"] = errors;
+ }
+
output["sources"] = Json::Value(Json::objectValue);
for (auto const& source: _sources)
{