Skip to content

Commit 13c88a1

Browse files
authored
fix: disallow relative paths in user-supplied cache dir (#182)
* fix: disallow relative paths in user-supplied cache dir * fix test
1 parent dcea707 commit 13c88a1

2 files changed

Lines changed: 27 additions & 2 deletions

File tree

src/semble/cache.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import hashlib
22
import json
3+
import logging
34
import os
45
import shutil
56
import sys
@@ -13,6 +14,8 @@
1314
from semble.types import ContentType
1415
from semble.utils import is_git_url, resolve_model_name
1516

17+
logger = logging.getLogger(__name__)
18+
1619
if TYPE_CHECKING:
1720
from semble.index import SembleIndex
1821

@@ -48,11 +51,24 @@ def _linux_cache_dir(name: str) -> Path:
4851
return base / name
4952

5053

54+
def _get_valid_user_cache_dir() -> Path | None:
55+
"""Gets the user cache dir if it is set and is a valid path."""
56+
user_cache_location = os.getenv("SEMBLE_CACHE_LOCATION")
57+
if user_cache_location is None:
58+
return None
59+
user_cache_dir = Path(user_cache_location)
60+
if not user_cache_dir.is_absolute():
61+
logger.warning("SEMBLE_CACHE_LOCATION is not an absolute path: %s", user_cache_location)
62+
return None
63+
64+
return user_cache_dir
65+
66+
5167
def resolve_cache_folder() -> Path:
5268
"""Resolves a cache folder, respects SEMBLE_CACHE_LOCATION (highest precedence), XDG_CACHE_HOME."""
5369
name = "semble"
54-
if semble_cache_location := os.getenv("SEMBLE_CACHE_LOCATION"):
55-
cache_dir = Path(semble_cache_location)
70+
if user_cache_dir := _get_valid_user_cache_dir():
71+
cache_dir = user_cache_dir
5672
elif sys.platform == "win32":
5773
cache_dir = _windows_cache_dir(name)
5874
elif sys.platform == "darwin":

tests/test_cache.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import pytest
99

1010
from semble.cache import (
11+
_get_valid_user_cache_dir,
1112
_linux_cache_dir,
1213
_windows_cache_dir,
1314
clear_cache,
@@ -93,6 +94,14 @@ def test_resolve_cache_folder(platform: str, mock_target: str, expected: Path) -
9394
assert result == expected
9495

9596

97+
def test_get_valid_user_cache_dir_relative_path() -> None:
98+
"""_get_valid_user_cache_dir returns None when SEMBLE_CACHE_LOCATION is a relative path."""
99+
with patch.dict("os.environ", {"SEMBLE_CACHE_LOCATION": "relative/path"}):
100+
with patch("semble.cache.logger") as mock_logger:
101+
assert _get_valid_user_cache_dir() is None
102+
mock_logger.warning.assert_called_once()
103+
104+
96105
def test_resolve_cache_folder_semble_cache_location(tmp_path: Path) -> None:
97106
"""SEMBLE_CACHE_LOCATION takes precedence over all platform-specific helpers."""
98107
custom = tmp_path / "custom_cache"

0 commit comments

Comments
 (0)