diff --git a/Frameworks/io/src/path.cc b/Frameworks/io/src/path.cc index 04cef7c8..a4f8caa0 100644 --- a/Frameworks/io/src/path.cc +++ b/Frameworks/io/src/path.cc @@ -178,6 +178,17 @@ namespace path return !path.empty() && path[0] == '/' ? normalize(path) : normalize(base + "/" + path); } + bool is_absolute (std::string const& path) + { + if(!path.empty() && path[0] == '/') + { + std::string p = normalize(path); + if(p != "/.." && p.find("/../") != 0) + return true; + } + return false; + } + std::string with_tilde (std::string const& p) { std::string const& base = home(); diff --git a/Frameworks/io/src/path.h b/Frameworks/io/src/path.h index 8ef175b4..5f8e2f0d 100644 --- a/Frameworks/io/src/path.h +++ b/Frameworks/io/src/path.h @@ -21,6 +21,7 @@ namespace path PUBLIC std::string join (std::string const& base, std::string const& path); // this will normalize the (resulting) path + PUBLIC bool is_absolute (std::string const& path); PUBLIC std::string with_tilde (std::string const& path); // /Users/me/foo.html.erb → ~/foo.html.erb PUBLIC std::string relative_to (std::string const& path, std::string const& base); // /Users/me/foo.html.erb (arg: ~/Desktop) → ../foo.html.erb diff --git a/Frameworks/io/tests/t_path.cc b/Frameworks/io/tests/t_path.cc index 76c68d22..12c688fd 100644 --- a/Frameworks/io/tests/t_path.cc +++ b/Frameworks/io/tests/t_path.cc @@ -93,6 +93,26 @@ public: TS_ASSERT_EQUALS(path::join("foo/bar", "fud"), "foo/bar/fud"); } + void test_is_absolute () + { + TS_ASSERT_EQUALS(path::is_absolute("../"), false); + TS_ASSERT_EQUALS(path::is_absolute("../foo"), false); + TS_ASSERT_EQUALS(path::is_absolute("./"), false); + TS_ASSERT_EQUALS(path::is_absolute("/."), true); + TS_ASSERT_EQUALS(path::is_absolute("/.."), false); + TS_ASSERT_EQUALS(path::is_absolute("/../"), false); + TS_ASSERT_EQUALS(path::is_absolute("/../tmp"), false); // this path is actually valid, so might revise path::normalize() + TS_ASSERT_EQUALS(path::is_absolute("/./.."), false); + TS_ASSERT_EQUALS(path::is_absolute("/./../tmp"), false); // this path is actually valid, so might revise path::normalize() + TS_ASSERT_EQUALS(path::is_absolute("/./foo"), true); + TS_ASSERT_EQUALS(path::is_absolute("//."), true); + TS_ASSERT_EQUALS(path::is_absolute("//../../foo"), false); + TS_ASSERT_EQUALS(path::is_absolute("//./foo"), true); + TS_ASSERT_EQUALS(path::is_absolute("/foo/.."), true); + TS_ASSERT_EQUALS(path::is_absolute("/foo/../.."), false); + TS_ASSERT_EQUALS(path::is_absolute("foo"), false); + } + void test_with_tilde () { using namespace path;