Skip to content

Commit

Permalink
Enable new tarfile extraction protections in Python 3.12
Browse files Browse the repository at this point in the history
  • Loading branch information
rmartin16 committed May 25, 2023
1 parent ab488e5 commit 928e391
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 1 deletion.
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ no-cover-if-is-macos = "'darwin' == os_environ.get('COVERAGE_PLATFORM', sys_plat
no-cover-if-not-macos = "'darwin' != os_environ.get('COVERAGE_PLATFORM', sys_platform) and os_environ.get('COVERAGE_EXCLUDE_PLATFORM') != 'disable'"
no-cover-if-is-windows = "'win32' == os_environ.get('COVERAGE_PLATFORM', sys_platform) and os_environ.get('COVERAGE_EXCLUDE_PLATFORM') != 'disable'"
no-cover-if-not-windows = "'win32' != os_environ.get('COVERAGE_PLATFORM', sys_platform) and os_environ.get('COVERAGE_EXCLUDE_PLATFORM') != 'disable'"
no-cover-if-lt-py312 = "sys_version_info < (3, 12) and os_environ.get('COVERAGE_EXCLUDE_PYTHON_VERSION') != 'disable'"
no-cover-if-is-py310 = "python_version == '3.10' and os_environ.get('COVERAGE_EXCLUDE_PYTHON_VERSION') != 'disable'"
no-cover-if-lt-py310 = "sys_version_info < (3, 10) and os_environ.get('COVERAGE_EXCLUDE_PYTHON_VERSION') != 'disable'"
no-cover-if-gte-py310 = "sys_version_info > (3, 10) and os_environ.get('COVERAGE_EXCLUDE_PYTHON_VERSION') != 'disable'"
Expand Down
10 changes: 10 additions & 0 deletions src/briefcase/commands/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,12 +283,22 @@ def _unpack_support_package(self, support_file_path, support_path):
:param support_file_path: The path to the support file to be unpacked.
:param support_path: The path where support files should be unpacked.
"""
# Additional protections for unpacking tar files were introduced in Python 3.12.
# This enables the behavior that will be the default in Python 3.14.
# However, the protections can only be enabled for tar files...not zip files.
is_zip = support_file_path.name.endswith("zip")
if sys.version_info >= (3, 12) and not is_zip: # pragma: no-cover-if-lt-py312
tarfile_kwargs = {"filter": "data"}
else:
tarfile_kwargs = {}

try:
with self.input.wait_bar("Unpacking support package..."):
support_path.mkdir(parents=True, exist_ok=True)
self.tools.shutil.unpack_archive(
support_file_path,
extract_dir=support_path,
**tarfile_kwargs,
)
except (shutil.ReadError, EOFError) as e:
raise InvalidSupportPackage(support_file_path) from e
Expand Down
7 changes: 6 additions & 1 deletion src/briefcase/integrations/android_sdk.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import shlex
import shutil
import subprocess
import sys
import time
from contextlib import suppress
from pathlib import Path
Expand Down Expand Up @@ -604,7 +605,11 @@ def verify_emulator_skin(self, skin):
# Unpack skin archive
with self.tools.input.wait_bar("Installing device skin..."):
try:
self.tools.shutil.unpack_archive(skin_tgz_path, extract_dir=skin_path)
self.tools.shutil.unpack_archive(
skin_tgz_path,
extract_dir=skin_path,
**({"filter": "data"} if sys.version_info >= (3, 12) else {}),
)
except (shutil.ReadError, EOFError) as err:
raise BriefcaseCommandError(
f"Unable to unpack {skin} device skin."
Expand Down
3 changes: 3 additions & 0 deletions tests/commands/create/test_install_app_support_package.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import shutil
import sys
from unittest import mock

import pytest
Expand Down Expand Up @@ -55,6 +56,7 @@ def test_install_app_support_package(
create_command.tools.shutil.unpack_archive.assert_called_with(
tmp_path / "data" / "support" / "Python-3.X-tester-support.b37.tar.gz",
extract_dir=support_path,
**({"filter": "data"} if sys.version_info >= (3, 12) else {}),
)

# Confirm that the full path to the support file
Expand Down Expand Up @@ -100,6 +102,7 @@ def test_install_pinned_app_support_package(
create_command.tools.shutil.unpack_archive.assert_called_with(
tmp_path / "data" / "support" / "Python-3.X-Tester-support.b42.tar.gz",
extract_dir=support_path,
**({"filter": "data"} if sys.version_info >= (3, 12) else {}),
)

# Confirm that the full path to the support file
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import sys
from pathlib import Path
from unittest.mock import MagicMock

Expand Down Expand Up @@ -42,6 +43,7 @@ def test_new_skin(mock_tools, android_sdk):
mock_tools.shutil.unpack_archive.assert_called_once_with(
skin_tgz_path,
extract_dir=android_sdk.root_path / "skins" / "pixel_X",
**({"filter": "data"} if sys.version_info >= (3, 12) else {}),
)

# Original file was deleted.
Expand Down Expand Up @@ -108,6 +110,7 @@ def test_unpack_failure(mock_tools, android_sdk, tmp_path):
mock_tools.shutil.unpack_archive.assert_called_once_with(
skin_tgz_path,
extract_dir=android_sdk.root_path / "skins" / "pixel_X",
**({"filter": "data"} if sys.version_info >= (3, 12) else {}),
)

# Original file wasn't deleted.
Expand Down

0 comments on commit 928e391

Please sign in to comment.