Opened 5 years ago
Last modified 5 years ago
#13028 new Bugs
boost::filesystem::canonical(const path& p, system::error_code& ec) throws exception
Reported by: | Owned by: | Beman Dawes | |
---|---|---|---|
Milestone: | To Be Determined | Component: | filesystem |
Version: | Boost 1.65.0 | Severity: | Problem |
Keywords: | Cc: |
Description
Per the docs, this function should report filesystem errors through the error_code. In the case of permission issues, this contract is violated.
This is best explained with the test case:
#include <boost/detail/lightweight_test_report.hpp> #include <boost/filesystem.hpp> namespace fs = boost::filesystem; int test_main(int, char*[]) { // Ensure that we do not have read permissions on pwd fs::path tmp_path = fs::temp_directory_path(); fs::path unique_path = fs::unique_path(); fs::path dir_path = tmp_path / unique_path; fs::create_directory(dir_path); fs::current_path(dir_path); fs::permissions(dir_path, fs::no_perms); // Try to get a canonical path with the error_code API. This should return an // error through the error_code, but instead throws an exception (because // canonical(const path& p, system::error_code& ec) calls current_path() // without error_code) boost::system::error_code e; fs::canonical("foo", e); BOOST_TEST(e.value() != 0); return ::boost::report_errors(); }
Test output:
bin/bug Clang version 8.0.0 (clang-800.0.38), __GXX_EXPERIMENTAL_CXX0X__ not defined libc++ version 3700 Mac OS Boost version 1.65.0 Command line: bin/bug ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ****************************** std::exception ***************************** boost::filesystem::current_path: Permission denied ***************************************************************************
This unexpected exception causes a crash in osquery. See https://github.com/facebook/osquery/issues/3279
Note:
See TracTickets
for help on using tickets.
I just ran into the same issue in one of our internal applications. There are actually 2 bugs causing the same problem. The first is that the
canonical(const path& p, system::error_code& ec)
callscurrent_path()
without passing in theerror_code
. However, when that is fixed, then same problem shows up again if you pass in a relative path asbase
becausedetail::canonical()
immediately callsabsolute()
, which in turn callscurrent_path()
.It's easy to fix by simply calling the no except version of
current_path()
in both places (although, sinceabsolute()
doesn't take anerror_code
, it can get a bit wordy):operations.hpp:
operations.cpp