CommonIO: Make readFile() check if the file is not a directory and if not fail with a sensible exception rather than std::length_error

This commit is contained in:
Kamil Śliwak 2021-06-25 14:21:44 +02:00
parent cbf1c3ae69
commit 65e23ff171
6 changed files with 29 additions and 0 deletions

View File

@ -43,9 +43,17 @@ namespace
template <typename T>
inline T readFile(std::string const& _file)
{
assertThrow(boost::filesystem::exists(_file), FileNotFound, _file);
// ifstream does not always fail when the path leads to a directory. Instead it might succeed
// with tellg() returning a nonsensical value so that std::length_error gets raised in resize().
assertThrow(boost::filesystem::is_regular_file(_file), NotAFile, _file);
T ret;
size_t const c_elementSize = sizeof(typename T::value_type);
std::ifstream is(_file, std::ifstream::binary);
// Technically, this can still fail even though we checked above because FS content can change at any time.
assertThrow(is, FileNotFound, _file);
// get length of file:

View File

@ -33,6 +33,7 @@ namespace solidity::util
/// Retrieve and returns the contents of the given file as a std::string.
/// If the file doesn't exist, it will throw a FileNotFound exception.
/// If the file exists but is not a regular file, it will throw NotAFile exception.
/// If the file is empty, returns an empty string.
std::string readFileAsString(std::string const& _file);

View File

@ -49,6 +49,7 @@ DEV_SIMPLE_EXCEPTION(InvalidAddress);
DEV_SIMPLE_EXCEPTION(BadHexCharacter);
DEV_SIMPLE_EXCEPTION(BadHexCase);
DEV_SIMPLE_EXCEPTION(FileNotFound);
DEV_SIMPLE_EXCEPTION(NotAFile);
DEV_SIMPLE_EXCEPTION(DataTooLong);
DEV_SIMPLE_EXCEPTION(StringTooLong);

View File

@ -668,6 +668,10 @@ bool CommandLineInterface::parseLibraryOption(string const& _input)
{
// Should not happen if `fs::is_regular_file` is correct.
}
catch (NotAFile const&)
{
// Should not happen if `fs::is_regular_file` is correct.
}
vector<string> libraries;
boost::split(libraries, data, boost::is_space() || boost::is_any_of(","), boost::token_compress_on);
@ -1263,6 +1267,11 @@ bool CommandLineInterface::processInput()
serr() << "File not found: " << jsonFile << endl;
return false;
}
catch (NotAFile const&)
{
serr() << "Not a regular file: " << jsonFile << endl;
return false;
}
}
StandardCompiler compiler(m_fileReader.reader());
sout() << compiler.compile(std::move(input)) << endl;

View File

@ -282,6 +282,11 @@ Allowed options)",
cerr << "File not found:" << _exception.comment() << endl;
return 1;
}
catch (NotAFile const& _exception)
{
cerr << "Not a regular file:" << _exception.comment() << endl;
return 1;
}
if (arguments.count("input-file"))
YulOpti{}.runInteractive(input);

View File

@ -148,6 +148,11 @@ Allowed options)",
cerr << "File not found: " << path << endl;
return 1;
}
catch (NotAFile const&)
{
cerr << "Not a regular file: " << path << endl;
return 1;
}
}
else
input = readStandardInput();