aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/src
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2016-09-28 19:02:25 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2016-09-28 19:02:25 +0100
commitfd5effb17e5f800fcaf54fc1223b77fa764b7f72 (patch)
tree8768b2c522ddcd29a552fd09838f7179502163de /libstdc++-v3/src
parent93c9b105be716efa6ede687f5bc6af6d5224a0de (diff)
downloadgcc-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.cc30
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());
}