From 758c5b9d047b90651e14414f61fa7a4de97c5260 Mon Sep 17 00:00:00 2001
From: Daira Hopwood <daira@jacaranda.org>
Date: Mon, 2 Nov 2015 22:00:31 +0000
Subject: [PATCH] Fix a corner case for to_filepath on Windows to make it
 consistent with Unix.

Signed-off-by: Daira Hopwood <daira@jacaranda.org>
---
 src/allmydata/test/test_encodingutil.py | 8 ++++++++
 src/allmydata/util/encodingutil.py      | 9 ++++++++-
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/src/allmydata/test/test_encodingutil.py b/src/allmydata/test/test_encodingutil.py
index 3650daf8..49db1d18 100644
--- a/src/allmydata/test/test_encodingutil.py
+++ b/src/allmydata/test/test_encodingutil.py
@@ -447,6 +447,14 @@ class QuotePaths(ReallyEqualMixin, unittest.TestCase):
         self.failUnlessReallyEqual(quote_filepath(foo_bar_fp, quotemarks=False),
                                    win32_other("C:\\foo\\bar", "/foo/bar"))
 
+        foo_longfp = FilePath(u'\\\\?\\C:\\foo')
+        self.failUnlessReallyEqual(quote_filepath(foo_longfp),
+                                   win32_other("'C:\\foo'", "'\\\\?\\C:\\foo'"))
+        self.failUnlessReallyEqual(quote_filepath(foo_longfp, quotemarks=True),
+                                   win32_other("'C:\\foo'", "'\\\\?\\C:\\foo'"))
+        self.failUnlessReallyEqual(quote_filepath(foo_longfp, quotemarks=False),
+                                   win32_other("C:\\foo", "\\\\?\\C:\\foo"))
+
 
 class FilePaths(ReallyEqualMixin, unittest.TestCase):
     def test_to_filepath(self):
diff --git a/src/allmydata/util/encodingutil.py b/src/allmydata/util/encodingutil.py
index de40482b..65f5911a 100644
--- a/src/allmydata/util/encodingutil.py
+++ b/src/allmydata/util/encodingutil.py
@@ -274,11 +274,18 @@ def extend_filepath(fp, segments):
         return fp
 
 def to_filepath(path):
-    precondition(isinstance(path, basestring), path=path)
+    precondition(isinstance(path, unicode if use_unicode_filepath else basestring),
+                 path=path)
 
     if isinstance(path, unicode) and not use_unicode_filepath:
         path = path.encode(filesystem_encoding)
 
+    if sys.platform == "win32":
+        _assert(isinstance(path, unicode), path=path)
+        if path.startswith(u"\\\\?\\") and len(path) > 4:
+            # FilePath normally strips trailing path separators, but not in this case.
+            path = path.rstrip(u"\\")
+
     return FilePath(path)
 
 def _decode(s):
-- 
2.45.2