8000 gh-108948: tarfile should handle sticky bit in FreeBSD by sorcio · Pull Request #108950 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-108948: tarfile should handle sticky bit in FreeBSD #108950

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 21 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
test exception branches
  • Loading branch information
sorcio committed Sep 6, 2023
commit 400957365010039140bfb807b20077c93895324b
26 changes: 26 additions & 0 deletions Lib/test/test_tarfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,32 @@ def format_mtime(mtime):
tar.close()
os_helper.rmtree(DIR)

@unittest.skipUnless(hasattr(errno, "EFTYPE"), "errno.EFTYPE required")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to mock this constant to test the code on other platforms?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to go with it. Maybe it's overkill for such a niche case, but more tests rarely hurt. All new tests never skip.

def test_extract_chmod_eftype(self):
# Extracting a file as non-root should skip the sticky bit (gh-108948)
# even on platforms where chmod fails with EFTYPE (i.e. FreeBSD). But
# we need to take care that any other error is preserved.
with ArchiveMaker() as arc:
arc.add("sticky", mode="?rw-rw-rwt")
tar = arc.open(errorlevel=2)
DIR = os.path.join(TEMPDIR, "chmod")
os.mkdir(DIR)
try:
# this should not raise:
tar.extract("sticky", DIR)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you check permissions of the created file? Please add also an empty line for readability.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you check permissions of the created file?

Do you mean to stat the file and add an assertion that the flags are as expected? Sure, it's a good idea. The result would depend on whether the test code is run as root or not. Would it be fair to skip if running as root?

Copy link
Member
@vstinner vstinner Sep 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I expect that if run as root, the test sets the sticky bit. Otherwise, it doesn't. Python has a Cirrus CI job which runs the Python test suite on FreeBSD... as root!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, already did it in the new commit.

Besides, pretty nice to have at least one test runner as root! (Well, assuming it works out with Cirrus credits)

# but we can create a situation where it does raise:
with unittest.mock.patch("os.chmod") as mock:
eftype_error = OSError(errno.EFTYPE, "EFTYPE")
other_error = OSError(errno.EPERM, "different error")
mock.side_effect = [eftype_error, other_error]
with self.assertRaises(tarfile.ExtractError) as excinfo:
tar.extract("sticky", DIR)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please test somewhere that the ExtractError error message is "could not change mode"?

Can you use a different name? extract("sticky", DIR) could also fail because the file already exists. Maybe add "sticky2" to the archive.

self.assertEqual(excinfo.exception.__cause__, other_error)
self.assertEqual(excinfo.exception.__cause__.__cause__, eftype_error)
finally:
os_helper.rmtree(DIR)
tar.close()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead, you can use with tar: and self.addCleanup(os_helper.rmtree, DIR) above.


@os_helper.skip_unless_working_chmod
def test_extract_directory(self):
dirtype = "ustar/dirtype"
Expand Down
0