From 9f67d26a1ae83e8681c628e0dc8475c2e3cc8519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sat, 14 Nov 2020 02:58:13 +0100 Subject: [PATCH] CommandLineInterface: Fix output directory creation for paths ending with a slash and equivalent but not equal to dot or double dot --- Changelog.md | 1 + solc/CommandLineInterface.cpp | 15 +++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Changelog.md b/Changelog.md index 002276b6d..a3b765391 100644 --- a/Changelog.md +++ b/Changelog.md @@ -27,6 +27,7 @@ Bugfixes: * SMTChecker: Fix false negative in modifier applied multiple times. * SMTChecker: Fix internal error in the BMC engine when inherited contract from a different source unit has private state variables. * SMTChecker: Fix internal error when ``array.push()`` is used as the LHS of an assignment. + * Command Line Interface: Fix write error when the directory passed to ``--output-dir`` ends with a slash. * SMTChecker: Fix CHC false positives when branches are used inside modifiers. * Code generator: Fix missing creation dependency tracking for abstract contracts. diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index e1c98dcef..aabe0be53 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -730,12 +730,15 @@ map CommandLineInterface::parseAstFromInput() void CommandLineInterface::createFile(string const& _fileName, string const& _data) { namespace fs = boost::filesystem; - // create directory if not existent - fs::path p(m_args.at(g_argOutputDir).as()); - // Do not try creating the directory if the first item is . or .. - if (p.filename() != "." && p.filename() != "..") - fs::create_directories(p); - string pathName = (p / _fileName).string(); + + fs::path outputDir(m_args.at(g_argOutputDir).as()); + + // NOTE: create_directories() raises an exception if the path consists solely of '.' or '..' + // (or equivalent such as './././.'). Paths like 'a/b/.' and 'a/b/..' are fine though. + // The simplest workaround is to use an absolute path. + fs::create_directories(fs::absolute(outputDir)); + + string pathName = (outputDir / _fileName).string(); if (fs::exists(pathName) && !m_args.count(g_strOverwrite)) { serr() << "Refusing to overwrite existing file \"" << pathName << "\" (use --" << g_strOverwrite << " to force)." << endl;