aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog.md1
-rw-r--r--solc/CommandLineInterface.cpp11
-rw-r--r--solc/CommandLineInterface.h5
-rw-r--r--solc/main.cpp7
-rwxr-xr-xtest/cmdlineTests.sh14
5 files changed, 33 insertions, 5 deletions
diff --git a/Changelog.md b/Changelog.md
index 89c0d883..8e9780c0 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,6 +1,7 @@
### 0.4.10 (unreleased)
Features:
+ * Commandline interface: Do not overwrite files unless forced.
* Add ``assert(condition)``, which throws if condition is false.
* Introduce ``.transfer(value)`` for sending Ether.
* Code generator: Support ``revert()`` to abort with rolling back, but not consuming all gas.
diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp
index 6759727f..0c777c77 100644
--- a/solc/CommandLineInterface.cpp
+++ b/solc/CommandLineInterface.cpp
@@ -93,6 +93,7 @@ static string const g_strOpcodes = "opcodes";
static string const g_strOptimize = "optimize";
static string const g_strOptimizeRuns = "optimize-runs";
static string const g_strOutputDir = "output-dir";
+static string const g_strOverwrite = "overwrite";
static string const g_strSignatureHashes = "hashes";
static string const g_strSources = "sources";
static string const g_strSourceList = "sourceList";
@@ -465,6 +466,12 @@ void CommandLineInterface::createFile(string const& _fileName, string const& _da
if (p.filename() != "." && p.filename() != "..")
fs::create_directories(p);
string pathName = (p / _fileName).string();
+ if (fs::exists(pathName) && !m_args.count(g_strOverwrite))
+ {
+ cerr << "Refusing to overwrite existing file \"" << pathName << "\" (use --overwrite to force)." << endl;
+ m_error = true;
+ return;
+ }
ofstream outFile(pathName);
outFile << _data;
if (!outFile)
@@ -510,6 +517,7 @@ Allowed options)",
po::value<string>()->value_name("path"),
"If given, creates one file per component and contract/file at the specified directory."
)
+ (g_strOverwrite.c_str(), "Overwrite existing files (used together with -o).")
(
g_argCombinedJson.c_str(),
po::value<string>()->value_name(boost::join(g_combinedJsonArgs, ",")),
@@ -858,7 +866,7 @@ void CommandLineInterface::handleAst(string const& _argStr)
}
}
-void CommandLineInterface::actOnInput()
+bool CommandLineInterface::actOnInput()
{
if (m_onlyAssemble)
outputAssembly();
@@ -866,6 +874,7 @@ void CommandLineInterface::actOnInput()
writeLinkedFiles();
else
outputCompilationResults();
+ return !m_error;
}
bool CommandLineInterface::link()
diff --git a/solc/CommandLineInterface.h b/solc/CommandLineInterface.h
index bcfc43d7..f52a03c7 100644
--- a/solc/CommandLineInterface.h
+++ b/solc/CommandLineInterface.h
@@ -47,7 +47,8 @@ public:
/// Parse the files and create source code objects
bool processInput();
/// Perform actions on the input depending on provided compiler arguments
- void actOnInput();
+ /// @returns true on success.
+ bool actOnInput();
private:
bool link();
@@ -81,6 +82,8 @@ private:
/// @arg _data to be written
void createFile(std::string const& _fileName, std::string const& _data);
+ bool m_error = false; ///< If true, some error occurred.
+
bool m_onlyAssemble = false;
bool m_onlyLink = false;
diff --git a/solc/main.cpp b/solc/main.cpp
index 28726e26..c61da6e9 100644
--- a/solc/main.cpp
+++ b/solc/main.cpp
@@ -58,15 +58,16 @@ int main(int argc, char** argv)
return 1;
if (!cli.processInput())
return 1;
+ bool success = false;
try
{
- cli.actOnInput();
+ success = cli.actOnInput();
}
catch (boost::exception const& _exception)
{
cerr << "Exception during output generation: " << boost::diagnostic_information(_exception) << endl;
- return 1;
+ success = false;
}
- return 0;
+ return success ? 0 : 1;
}
diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh
index cb714efe..fc04bd7d 100755
--- a/test/cmdlineTests.sh
+++ b/test/cmdlineTests.sh
@@ -50,9 +50,23 @@ echo "Testing library checksum..."
echo '' | "$SOLC" --link --libraries a:0x90f20564390eAe531E810af625A22f51385Cd222
! echo '' | "$SOLC" --link --libraries a:0x80f20564390eAe531E810af625A22f51385Cd222 2>/dev/null
+echo "Testing overwriting files"
+TMPDIR=$(mktemp -d)
+(
+ set -e
+ # First time it works
+ echo 'contract C {} ' | "$SOLC" --bin -o "$TMPDIR/non-existing-stuff-to-create" 2>/dev/null
+ # Second time it fails
+ ! echo 'contract C {} ' | "$SOLC" --bin -o "$TMPDIR/non-existing-stuff-to-create" 2>/dev/null
+ # Unless we force
+ echo 'contract C {} ' | "$SOLC" --overwrite --bin -o "$TMPDIR/non-existing-stuff-to-create" 2>/dev/null
+)
+rm -rf "$TMPDIR"
+
echo "Testing soljson via the fuzzer..."
TMPDIR=$(mktemp -d)
(
+ set -e
cd "$REPO_ROOT"
REPO_ROOT=$(pwd) # make it absolute
cd "$TMPDIR"