diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2016-09-28 19:02:25 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2016-09-28 19:02:25 +0100 |
commit | fd5effb17e5f800fcaf54fc1223b77fa764b7f72 (patch) | |
tree | 8768b2c522ddcd29a552fd09838f7179502163de /libstdc++-v3/src | |
parent | 93c9b105be716efa6ede687f5bc6af6d5224a0de (diff) | |
download | gcc-fd5effb17e5f800fcaf54fc1223b77fa764b7f72.zip gcc-fd5effb17e5f800fcaf54fc1223b77fa764b7f72.tar.gz gcc-fd5effb17e5f800fcaf54fc1223b77fa764b7f72.tar.bz2 |
Check for overflow in filesystem::last_write_time
* include/experimental/bits/fs_fwd.h (file_time_type): Simplify
definition.
* src/filesystem/ops.cc (file_time): Take error_code parameter and
check for overflow.
(do_copy_file, last_write_time): Pass error_code in file_time calls.
* testsuite/experimental/filesystem/operations/last_write_time.cc:
New.
* testsuite/util/testsuite_fs.h (scoped_file): Define RAII helper.
From-SVN: r240587
Diffstat (limited to 'libstdc++-v3/src')
-rw-r--r-- | libstdc++-v3/src/filesystem/ops.cc | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/libstdc++-v3/src/filesystem/ops.cc b/libstdc++-v3/src/filesystem/ops.cc index 0ecb8b9..659cfbb 100644 --- a/libstdc++-v3/src/filesystem/ops.cc +++ b/libstdc++-v3/src/filesystem/ops.cc @@ -288,16 +288,24 @@ namespace } inline fs::file_time_type - file_time(const stat_type& st) noexcept + file_time(const stat_type& st, std::error_code& ec) noexcept { using namespace std::chrono; - return fs::file_time_type{ #ifdef _GLIBCXX_USE_ST_MTIM - seconds{st.st_mtim.tv_sec} + nanoseconds{st.st_mtim.tv_nsec} + time_t s = st.st_mtim.tv_sec; + nanoseconds ns{st.st_mtim.tv_nsec}; #else - seconds{st.st_mtime} + time_t s = st.st_mtime; + nanoseconds ns{}; #endif - }; + + if (s >= (nanoseconds::max().count() / 1e9)) + { + ec = std::make_error_code(std::errc::value_too_large); // EOVERFLOW + return fs::file_time_type::min(); + } + ec.clear(); + return fs::file_time_type{seconds{s} + ns}; } // Returns true if the file descriptor was successfully closed, @@ -373,11 +381,11 @@ namespace } else if (is_set(option, opts::update_existing)) { - if (file_time(*from_st) <= file_time(*to_st)) - { - ec.clear(); - return false; - } + const auto from_mtime = file_time(*from_st, ec); + if (ec) + return false; + if ((from_mtime <= file_time(*to_st, ec)) || ec) + return false; } else if (!is_set(option, opts::overwrite_existing)) { @@ -1036,7 +1044,7 @@ fs::last_write_time(const path& p) fs::file_time_type fs::last_write_time(const path& p, error_code& ec) noexcept { - return do_stat(p, ec, [](const auto& st) { return file_time(st); }, + return do_stat(p, ec, [&ec](const auto& st) { return file_time(st, ec); }, file_time_type::min()); } |