Skip to content

Commit 871d9a5

Browse files
author
Googler
committed
no-op
PiperOrigin-RevId: 924925361
1 parent e5e8a3d commit 871d9a5

1 file changed

Lines changed: 27 additions & 1 deletion

File tree

lit_nlp/lib/file_cache.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,32 @@ def _fetch_content(
9090
progress.close()
9191

9292

93+
def _safe_zip_file_extractall(zip_file: zipfile.ZipFile, path: str) -> None:
94+
"""Extracts all members from a zip file to a directory, safely.
95+
96+
This function is a safer alternative to `zipfile.ZipFile.extractall` as it
97+
prevents directory traversal exploits by ensuring that all extracted files
98+
are within the specified `path`.
99+
100+
Args:
101+
zip_file: The ZipFile object to extract from.
102+
path: The destination directory.
103+
104+
Raises:
105+
ValueError: If a member's name attempts to traverse outside the `path`.
106+
"""
107+
for info in zip_file.infolist():
108+
# Construct the full path where the member would be extracted.
109+
extracted_path = os.path.join(path, info.filename)
110+
# Ensure the constructed path is still within the designated 'path'.
111+
# os.path.realpath is used to resolve any '..' components.
112+
real_path = os.path.realpath(extracted_path)
113+
base_path = os.path.realpath(path)
114+
if os.path.commonpath([base_path, real_path]) != base_path:
115+
raise ValueError(f'unsafe path encountered in zip file: {info.filename}')
116+
zip_file.extract(info, path)
117+
118+
93119
def _get_extacted_dir(output_path: str) -> str:
94120
"""Extracts and returns the directory containing the provided archive."""
95121
is_zip = zipfile.is_zipfile(output_path)
@@ -110,7 +136,7 @@ def _get_extacted_dir(output_path: str) -> str:
110136

111137
if is_zip:
112138
with zipfile.ZipFile(output_path, 'r') as zip_file:
113-
zip_file.extractall(output_extracted_path)
139+
_safe_zip_file_extractall(zip_file, output_extracted_path)
114140
zip_file.close()
115141
else:
116142
tar_file = tarfile.open(output_path)

0 commit comments

Comments
 (0)