[libcxx-commits] [libcxx] [libc++] Make std::filesystem::canonical throw when given empty path (PR #77223)
via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Jan 7 00:30:55 PST 2024
https://github.com/Yuki-cpp updated https://github.com/llvm/llvm-project/pull/77223
>From 19f5fb22944f79c672e192c75b90b3d94ad542c8 Mon Sep 17 00:00:00 2001
From: Leo <leo.ghafari at gmail.com>
Date: Sun, 7 Jan 2024 10:46:46 +0900
Subject: [PATCH 1/2] [libc++] Make std::filesystem::canonical throw when given
empty path
Adds a check for empty paths in std::filesystem::canonical and raise an
error accordingly. Since std::filesystem::weakly_canonical uses this function
and should not raise an error when given an empty path, it was updated
to return an empty path instead of the results of canonical.
---
libcxx/src/filesystem/operations.cpp | 6 +++--
.../fs.op.canonical/canonical.pass.cpp | 26 +++++++++++++++++++
2 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp
index 6bee340e0d15c8..8f5b70a071373d 100644
--- a/libcxx/src/filesystem/operations.cpp
+++ b/libcxx/src/filesystem/operations.cpp
@@ -82,6 +82,8 @@ path __canonical(path const& orig_p, error_code* ec) {
path cwd;
ErrorHandler<path> err("canonical", ec, &orig_p, &cwd);
+ if (orig_p.empty())
+ return err.report(capture_errno());
path p = __do_absolute(orig_p, &cwd, ec);
#if (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112) || defined(_LIBCPP_WIN32API)
std::unique_ptr<path::value_type, decltype(&::free)> hold(detail::realpath(p.c_str(), nullptr), &::free);
@@ -912,7 +914,7 @@ path __weakly_canonical(const path& p, error_code* ec) {
ErrorHandler<path> err("weakly_canonical", ec, &p);
if (p.empty())
- return __canonical("", ec);
+ return __current_path(ec);
path result;
path tmp;
@@ -935,7 +937,7 @@ path __weakly_canonical(const path& p, error_code* ec) {
--PP;
}
if (PP.State == PathParser::PS_BeforeBegin)
- result = __canonical("", ec);
+ result = __current_path(ec);
if (ec)
ec->clear();
if (DNEParts.empty())
diff --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.canonical/canonical.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.canonical/canonical.pass.cpp
index 0098fe8ee698ef..000fb47096ba19 100644
--- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.canonical/canonical.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.canonical/canonical.pass.cpp
@@ -92,6 +92,31 @@ static void test_dne_path()
}
}
+static void test_empty_path()
+{
+ std::error_code ec = GetTestEC();
+ {
+ const path ret = canonical(path{}, ec);
+ assert(ec != GetTestEC());
+ assert(ec);
+ assert(ret == path{});
+ }
+ {
+ TEST_THROWS_TYPE(filesystem_error, canonical(path{}));
+ }
+
+ ec = GetTestEC();
+ {
+ const path ret = canonical("", ec);
+ assert(ec != GetTestEC());
+ assert(ec);
+ assert(ret == path{});
+ }
+ {
+ TEST_THROWS_TYPE(filesystem_error, canonical(""));
+ }
+}
+
static void test_exception_contains_paths()
{
#ifndef TEST_HAS_NO_EXCEPTIONS
@@ -121,6 +146,7 @@ int main(int, char**) {
signature_test();
test_canonical();
test_dne_path();
+ test_empty_path();
test_exception_contains_paths();
return 0;
>From 614ec4b47f0c986092a95fc64e9f9f1b59de3f84 Mon Sep 17 00:00:00 2001
From: Leo <leo.ghafari at gmail.com>
Date: Sun, 7 Jan 2024 17:25:26 +0900
Subject: [PATCH 2/2] fixup! [libc++] Make std::filesystem::canonical throw
when given empty path
---
.../fs.op.canonical/canonical.pass.cpp | 39 ++++++++-----------
1 file changed, 17 insertions(+), 22 deletions(-)
diff --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.canonical/canonical.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.canonical/canonical.pass.cpp
index 000fb47096ba19..c5935f20510844 100644
--- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.canonical/canonical.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.canonical/canonical.pass.cpp
@@ -92,29 +92,24 @@ static void test_dne_path()
}
}
-static void test_empty_path()
-{
- std::error_code ec = GetTestEC();
- {
- const path ret = canonical(path{}, ec);
- assert(ec != GetTestEC());
- assert(ec);
- assert(ret == path{});
- }
- {
- TEST_THROWS_TYPE(filesystem_error, canonical(path{}));
- }
+static void test_empty_path() {
+ std::error_code ec = GetTestEC();
+ {
+ const path ret = canonical(path{}, ec);
+ assert(ec != GetTestEC());
+ assert(ec);
+ assert(ret == path{});
+ }
+ { TEST_THROWS_TYPE(filesystem_error, canonical(path{})); }
- ec = GetTestEC();
- {
- const path ret = canonical("", ec);
- assert(ec != GetTestEC());
- assert(ec);
- assert(ret == path{});
- }
- {
- TEST_THROWS_TYPE(filesystem_error, canonical(""));
- }
+ ec = GetTestEC();
+ {
+ const path ret = canonical("", ec);
+ assert(ec != GetTestEC());
+ assert(ec);
+ assert(ret == path{});
+ }
+ { TEST_THROWS_TYPE(filesystem_error, canonical("")); }
}
static void test_exception_contains_paths()
More information about the libcxx-commits
mailing list