return os.path.normpath(path) == path and os.path.isabs(path)
+def IsBelowDir(root, other_path):
+ """Check whether a path is below a root dir.
+
+ This works around the nasty byte-byte comparisation of commonprefix.
+
+ """
+ if not (os.path.isabs(root) and os.path.isabs(other_path)):
+ raise ValueError("Provided paths '%s' and '%s' are not absolute" %
+ (root, other_path))
+ prepared_root = "%s%s" % (os.path.normpath(root), os.sep)
+ return os.path.commonprefix([prepared_root,
+ os.path.normpath(other_path)]) == prepared_root
+
+
def PathJoin(*args):
"""Safe-join a list of path components.
self._pathTestHelper("/etc/", False)
+class TestIsBelowDir(unittest.TestCase):
+ """Testing case for IsBelowDir"""
+
+ def testSamePrefix(self):
+ self.assertTrue(utils.IsBelowDir("/a/b", "/a/b/c"))
+ self.assertTrue(utils.IsBelowDir("/a/b/", "/a/b/e"))
+
+ def testSamePrefixButDifferentDir(self):
+ self.assertFalse(utils.IsBelowDir("/a/b", "/a/bc/d"))
+ self.assertFalse(utils.IsBelowDir("/a/b/", "/a/bc/e"))
+
+ def testSamePrefixButDirTraversal(self):
+ self.assertFalse(utils.IsBelowDir("/a/b", "/a/b/../c"))
+ self.assertFalse(utils.IsBelowDir("/a/b/", "/a/b/../d"))
+
+ def testSamePrefixAndTraversal(self):
+ self.assertTrue(utils.IsBelowDir("/a/b", "/a/b/c/../d"))
+ self.assertTrue(utils.IsBelowDir("/a/b", "/a/b/c/./e"))
+ self.assertTrue(utils.IsBelowDir("/a/b", "/a/b/../b/./e"))
+
+ def testBothAbsPath(self):
+ self.assertRaises(ValueError, utils.IsBelowDir, "/a/b/c", "d")
+ self.assertRaises(ValueError, utils.IsBelowDir, "a/b/c", "/d")
+ self.assertRaises(ValueError, utils.IsBelowDir, "a/b/c", "d")
+
+
class TestPathJoin(unittest.TestCase):
"""Testing case for PathJoin"""