diff --git a/node/flatpak_node_generator/populate_pnpm_store.py b/node/flatpak_node_generator/populate_pnpm_store.py index 7501af60..46233e96 100644 --- a/node/flatpak_node_generator/populate_pnpm_store.py +++ b/node/flatpak_node_generator/populate_pnpm_store.py @@ -11,6 +11,7 @@ import time _SANITIZE_RE = re.compile(r'[\\/:*?"<>|]') +_MAX_LENGTH_WITHOUT_HASH = 120 def populate_store(manifest_path: str, tarball_dir: str, store_dir: str) -> None: @@ -134,6 +135,11 @@ def _process_tarball( json.dump(index_data, out) else: url_dir_name = re.sub(r'[:/]', '+', tarball_url) + if ( + len(url_dir_name) > _MAX_LENGTH_WITHOUT_HASH + or url_dir_name != url_dir_name.lower() + ): + url_dir_name = f'{url_dir_name[: _MAX_LENGTH_WITHOUT_HASH - 33]}_{hashlib.sha256(url_dir_name.encode()).hexdigest()[:32]}' url_idx_dir = os.path.join(store, url_dir_name) os.makedirs(url_idx_dir, exist_ok=True) url_idx_path = os.path.join(url_idx_dir, 'integrity.json') diff --git a/node/tests/test_populate_pnpm_store.py b/node/tests/test_populate_pnpm_store.py index 55780d0f..c9d0e940 100644 --- a/node/tests/test_populate_pnpm_store.py +++ b/node/tests/test_populate_pnpm_store.py @@ -1,3 +1,4 @@ +import hashlib import json import re import tarfile @@ -128,3 +129,53 @@ def test_process_tarball_with_tarball_url_v6(tmp_path: Path) -> None: url_idx_file = store_dir / url_dir_name / 'integrity.json' assert url_idx_file.exists() + + +def test_process_tarball_with_uppercase_path(tmp_path: Path) -> None: + tar_path = tmp_path / 'pkg.tgz' + store_dir = tmp_path / 'store' + tarball_url = 'https://example.com/PKG.tgz' + + _create_tarball(tar_path, {'package/index.js': "console.log('hello');"}) + + _process_tarball( + tarball_path=str(tar_path), + pkg_name='pkg', + pkg_version='1.0.0', + integrity_hex='a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2', + store=str(store_dir), + now=1234567890, + tarball_url=tarball_url, + store_version='v6', + ) + + sanitized_tarball_url = re.sub(r'[:/]', '+', tarball_url) + normalized_tarball_url = f'{sanitized_tarball_url}_{hashlib.sha256(sanitized_tarball_url.encode()).hexdigest()[:32]}' + url_idx_file = store_dir / normalized_tarball_url / 'integrity.json' + + assert url_idx_file.exists() + + +def test_process_tarball_with_long_path(tmp_path: Path) -> None: + tar_path = tmp_path / 'pkg.tgz' + store_dir = tmp_path / 'store' + tarball_url = f'https://example.com{"pkg" * 50}.tgz' + + _create_tarball(tar_path, {'package/index.js': "console.log('hello');"}) + + _process_tarball( + tarball_path=str(tar_path), + pkg_name='pkg', + pkg_version='1.0.0', + integrity_hex='a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2', + store=str(store_dir), + now=1234567890, + tarball_url=tarball_url, + store_version='v6', + ) + + sanitized_tarball_url = re.sub(r'[:/]', '+', tarball_url) + normalized_tarball_url = f'{sanitized_tarball_url[:87]}_{hashlib.sha256(sanitized_tarball_url.encode()).hexdigest()[:32]}' + url_idx_file = store_dir / normalized_tarball_url / 'integrity.json' + + assert url_idx_file.exists()