From 14e9635241fca41a7ba153040368256612ccb16f Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Tue, 14 Jun 2016 16:24:51 +0300 Subject: Check path validity in path::init() on Windows --- butl/path | 8 +++++++- butl/path.ixx | 2 +- butl/path.txx | 13 ++++++++++++- tests/path/driver.cxx | 4 +--- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/butl/path b/butl/path index 0645a4b..472e421 100644 --- a/butl/path +++ b/butl/path @@ -273,6 +273,10 @@ namespace butl // basic_path () {}; + // Constructors that take a path string as an argument throw + // invalid_basic_path if the string is not a valid path (e.g. uses + // unsupported notation on Windows). + // explicit basic_path (C const* s): base_type (s) {init (this->path_);} @@ -615,7 +619,9 @@ namespace butl // If exact is true, return whether the initialization was // successful, that is, the passed string is a valid path - // and no modifications were necessary. + // and no modifications were necessary. Throw invalid_basic_path + // if the string is not a valid path (e.g. uses unsupported notation on + // Windows). // bool init (string_type& s, bool exact = false); diff --git a/butl/path.ixx b/butl/path.ixx index 8dac717..1628ece 100644 --- a/butl/path.ixx +++ b/butl/path.ixx @@ -198,7 +198,7 @@ namespace butl { return absolute () #ifdef _WIN32 - // Disambiguate with dir_type(string_type,bool). + // Disambiguate with dir_type(string_type, bool). // ? dir_type (this->path_, static_cast (2)) #else diff --git a/butl/path.txx b/butl/path.txx index 56e2cf1..383f7fe 100644 --- a/butl/path.txx +++ b/butl/path.txx @@ -246,10 +246,21 @@ namespace butl bool basic_path:: init (string_type& s, bool exact) { + size_type n (s.size ()); + +#ifdef _WIN32 + // We do not support any special Windows path name notations like in C:abc, + // \\?\c:\abc, \\server\abc and \\?\UNC\server\abc (more about them at + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx). + // + if ((n > 2 && s[1] == ':' && s[2] != '\\' && s[2] != '/') || + (n > 1 && s[0] == '\\' && s[1] == '\\')) + throw invalid_basic_path (s); +#endif + // Strip trailing slashes except for the case where the single // slash represents the root directory. // - size_type n (s.size ()); for (; n > 1 && traits::is_separator (s[n - 1]); --n) ; if (n != s.size ()) diff --git a/tests/path/driver.cxx b/tests/path/driver.cxx index de8e8b1..f4b145a 100644 --- a/tests/path/driver.cxx +++ b/tests/path/driver.cxx @@ -34,14 +34,13 @@ main () assert (path ("//").string () == "/"); assert (path ("/tmp/foo/").string () == "/tmp/foo"); #ifdef _WIN32 - assert (path ("\\\\").string () == "\\"); assert (path ("/\\").string () == "/"); assert (path ("C:").string () == "C:"); assert (path ("C:\\").string () == "C:"); assert (path ("C:\\tmp\\foo\\").string () == "C:\\tmp\\foo"); #endif - // abslote/relative/root + // abslute/relative/root // #ifndef _WIN32 assert (path ("/").root ()); @@ -57,7 +56,6 @@ main () assert (path ("bar\\baz").relative ()); #endif - // leaf // #ifndef _WIN32 -- cgit v1.1