aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2016-06-14 16:24:51 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2016-06-18 15:05:38 +0300
commit14e9635241fca41a7ba153040368256612ccb16f (patch)
tree73c24c5ac047338cd7afffe97db29f3188b14445
parentd326f16dd40013e8bea639ff95c2b249e7867e5e (diff)
Check path validity in path::init() on Windows
-rw-r--r--butl/path8
-rw-r--r--butl/path.ixx2
-rw-r--r--butl/path.txx13
-rw-r--r--tests/path/driver.cxx4
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<size_type> (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<C, K>::
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<C> (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