diff options
-rw-r--r-- | gemato/recursiveloader.py | 9 | ||||
-rw-r--r-- | tests/test_recursiveloader.py | 32 |
2 files changed, 40 insertions, 1 deletions
diff --git a/gemato/recursiveloader.py b/gemato/recursiveloader.py index 4519aeb..1ea067e 100644 --- a/gemato/recursiveloader.py +++ b/gemato/recursiveloader.py @@ -48,6 +48,8 @@ class ManifestRecursiveLoader(object): gemato.verify.assert_path_verifies(path, verify_entry) with io.open(path, 'r', encoding='utf8') as f: m.load(f) + st = os.fstat(f.fileno()) + self.manifest_device = st.st_dev self.loaded_manifests[relpath] = m def _iter_manifests_for_path(self, path, recursive=False): @@ -197,7 +199,8 @@ class ManifestRecursiveLoader(object): def _verify_one_file(self, path, e, strict): try: - gemato.verify.assert_path_verifies(path, e) + gemato.verify.assert_path_verifies(path, e, + expected_dev=self.manifest_device) except gemato.exceptions.ManifestMismatch: if strict: raise @@ -238,6 +241,10 @@ class ManifestRecursiveLoader(object): dpath = os.path.join(relpath, d) de = entry_dict.pop(dpath, None) if de is None: + syspath = os.path.join(dirpath, d) + st = os.stat(syspath) + if st.st_dev != self.manifest_device: + raise gemato.exceptions.ManifestCrossDevice(syspath) continue if isinstance(de, gemato.manifest.ManifestEntryIGNORE): diff --git a/tests/test_recursiveloader.py b/tests/test_recursiveloader.py index c16e7ff..38a4a07 100644 --- a/tests/test_recursiveloader.py +++ b/tests/test_recursiveloader.py @@ -706,3 +706,35 @@ OPTIONAL foo m = gemato.recursiveloader.ManifestRecursiveLoader( os.path.join(self.dir, 'Manifest')) m.assert_directory_verifies('', strict=False) + + +class CrossDeviceManifestTest(TempDirTestCase): + """ + Test for a Manifest that crosses filesystem boundaries. + """ + + FILES = { + 'Manifest': u''' +DATA sub/version 0 MD5 d41d8cd98f00b204e9800998ecf8427e +''', + } + + def setUp(self): + super(CrossDeviceManifestTest, self).setUp() + os.symlink('/proc', os.path.join(self.dir, 'sub')) + + def tearDown(self): + os.unlink(os.path.join(self.dir, 'sub')) + super(CrossDeviceManifestTest, self).tearDown() + + def test_assert_directory_verifies(self): + m = gemato.recursiveloader.ManifestRecursiveLoader( + os.path.join(self.dir, 'Manifest')) + self.assertRaises(gemato.exceptions.ManifestCrossDevice, + m.assert_directory_verifies, '') + + def test_assert_directory_verifies_nonstrict(self): + m = gemato.recursiveloader.ManifestRecursiveLoader( + os.path.join(self.dir, 'Manifest')) + self.assertRaises(gemato.exceptions.ManifestCrossDevice, + m.assert_directory_verifies, '', strict=False) |