Skip to content

Commit 64456dc

Browse files
committed
fix(volumecache): normalize bytes dirs to text paths
A bytes dirs entry (e.g. dirs=b"/root/.cache") passed os.fspath unchanged, so os.walk yielded bytes names and _is_safe_dest compared bytes against str prefixes, raising TypeError that best-effort mode silently swallowed. Decode each entry with os.fsdecode so all _dirs are text. Add a regression test. Addresses review feedback on #531 (carried here as the superseding PR).
1 parent bec2c2e commit 64456dc

2 files changed

Lines changed: 18 additions & 1 deletion

File tree

‎runpod/serverless/utils/rp_volume_cache.py‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,10 @@ def __init__(
8080
# A bare path is one directory, not an iterable of path characters:
8181
# `dirs="/root/.cache"` must not be split into "/", "r", "o", ...
8282
dirs = [dirs]
83-
self._dirs = [os.path.realpath(os.fspath(d)) for d in dirs]
83+
# Normalize to text paths: a bytes entry (e.g. dirs=b"...") would keep
84+
# os.walk yielding bytes names and make _is_safe_dest compare bytes
85+
# against str prefixes, raising TypeError that best-effort mode swallows.
86+
self._dirs = [os.path.realpath(os.fsdecode(os.fspath(d))) for d in dirs]
8487
self._namespace = namespace or os.environ.get("RUNPOD_ENDPOINT_ID") or ""
8588
if self._namespace and (
8689
os.path.isabs(self._namespace)

‎tests/test_serverless/test_utils/test_rp_volume_cache.py‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,20 @@ def test_scalar_dirs_path_is_treated_as_single_dir(tmp_path):
9999
assert vc_list._dirs == expected # list input still works
100100

101101

102+
def test_bytes_dirs_are_normalized_to_text(tmp_path):
103+
# A bytes path must be decoded to text; otherwise os.walk yields bytes
104+
# names and _is_safe_dest compares bytes against str prefixes, raising a
105+
# TypeError that best-effort mode would silently swallow.
106+
vol = tmp_path / "volume"
107+
vol.mkdir()
108+
cache = tmp_path / "cache"
109+
expected = [os.path.realpath(str(cache))]
110+
111+
vc_bytes = VolumeCache(str(cache).encode(), namespace="ep1", volume_path=str(vol))
112+
assert vc_bytes._dirs == expected
113+
assert all(isinstance(d, str) for d in vc_bytes._dirs)
114+
115+
102116
# --------------------------------------------------------------------------- #
103117
# sync -> hydrate round trip
104118
# --------------------------------------------------------------------------- #

0 commit comments

Comments
 (0)