| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2841,9 +2841,11 @@ def makelink_with_filter(self, tarinfo, targetpath, | |||
| 2841 | 2841 | "makelink_with_filter: if filter_function is not None, " | |
| 2842 | 2842 | + "extraction_root must also not be None") | |
| 2843 | 2843 | try: | |
| 2844 | - filter_function( | ||
| 2844 | + filtered = filter_function( | ||
| 2845 | 2845 | unfiltered.replace(name=tarinfo.name, deep=False), | |
| 2846 | 2846 | extraction_root) | |
| 2847 | + if filtered is None: | ||
| 2848 | + return | ||
| 2847 | 2849 | filtered = filter_function(unfiltered, extraction_root) | |
| 2848 | 2850 | except _FILTER_ERRORS as cause: | |
| 2849 | 2851 | raise LinkFallbackError(tarinfo, unfiltered.name) from cause | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4621,9 +4621,15 @@ def test_sneaky_hardlink_fallback(self): | |||
| 4621 | 4621 | for filter in 'tar', 'fully_trusted': | |
| 4622 | 4622 | with self.subTest(filter), self.check_context(arc.open(), filter): | |
| 4623 | 4623 | if not os_helper.can_symlink(): | |
| 4624 | - self.expect_file("a/t/dummy") | ||
| 4625 | - self.expect_file("b/") | ||
| 4626 | - self.expect_file("c/") | ||
| 4624 | + if filter == 'tar': | ||
| 4625 | + self.expect_exception( | ||
| 4626 | + tarfile.LinkFallbackError, | ||
| 4627 | + "link 'boom' would be extracted as a copy of " | ||
| 4628 | + + "'c/escape', which was rejected") | ||
| 4629 | + else: | ||
| 4630 | + self.expect_file("a/t/dummy") | ||
| 4631 | + self.expect_file("b/") | ||
| 4632 | + self.expect_file("c/") | ||
| 4627 | 4633 | else: | |
| 4628 | 4634 | self.expect_file("a/t/dummy") | |
| 4629 | 4635 | self.expect_file("b/") | |
@@ -4820,6 +4826,25 @@ def testing_filter(member, path): | |||
| 4820 | 4826 | if os_helper.can_chmod(): | |
| 4821 | 4827 | self.assertFalse(path.stat().st_mode & stat.S_IWUSR) | |
| 4822 | 4828 | ||
| 4829 | + @symlink_test | ||
| 4830 | + def test_extract_filters_target_none(self): | ||
| 4831 | + # Test that when extract() falls back to extracting (rather than | ||
| 4832 | + # linking) a hardlink target, the member is skipped if the filter | ||
| 4833 | + # returns None. | ||
| 4834 | + with ArchiveMaker() as arc: | ||
| 4835 | + arc.add('a/b/s', symlink_to='../escape') | ||
| 4836 | + arc.add('q', hardlink_to='a/b/s') | ||
| 4837 | + def filter_unsafe_members(member, path): | ||
| 4838 | + try: | ||
| 4839 | + return tarfile.data_filter(member, path) | ||
| 4840 | + except tarfile.FilterError as error: | ||
| 4841 | + return None | ||
| 4842 | + with self.check_context(arc.open(), filter_unsafe_members): | ||
| 4843 | + if os_helper.can_symlink(): | ||
| 4844 | + self.expect_file('a/b/s', symlink_to='../escape') | ||
| 4845 | + else: | ||
| 4846 | + self.expect_file('a/b/') # symlink is not extracted | ||
| 4847 | + | ||
| 4823 | 4848 | def test_link_fallback_normalizes(self): | |
| 4824 | 4849 | # Make sure hardlink fallbacks work for non-normalized paths for all | |
| 4825 | 4850 | # filters | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,3 @@ | |||
| 1 | + In :mod:`tarfile`, when extracting a link falls back to extracting a member | ||
| 2 | + of the archive, skip the member when the filter function returns None when | ||
| 3 | + called with the extracted member's name replaced with the link's. | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments