@@ -25,7 +25,7 @@ def download_package(
2525 namespace : str = "preview" ,
2626 * ,
2727 force : bool = False ,
28- ) -> bool :
28+ ) -> None :
2929 """Downloads and extracts a Typst package to the local directory.
3030
3131 Args:
@@ -35,10 +35,6 @@ def download_package(
3535 namespace: The namespace of the package (e.g. "preview").
3636 force: If True, overwrite the package even if it already exists.
3737
38- Returns:
39- True if the package was downloaded and extracted, False if it was
40- skipped because it already exists and force was False.
41-
4238 Raises:
4339 ValueError: If a directory traversal is detected in the tarball.
4440 niquests.RequestException: If the package download fails.
@@ -51,25 +47,28 @@ def download_package(
5147 version ,
5248 dest_dir ,
5349 )
54- return False
50+ return
5551
5652 url = f"https://packages.typst.org/{ namespace } /{ name } -{ version } .tar.gz"
5753 logger .info ("Downloading %s..." , url )
5854 headers = {"User-Agent" : f"typvend/{ __version__ } " }
5955
60- try :
61- response = niquests .get (url , headers = headers , timeout = 30 )
62- response .raise_for_status ()
63- content = response .content
64- if not content :
65- msg = f"Failed to download package: no content received from { url } "
66- raise ValueError (msg )
67- except niquests .RequestException as e :
68- logger .error ("Failed to download package %s:%s: %s" , name , version , e )
69- raise
56+ response = niquests .get (url , headers = headers , timeout = 30 )
57+ response .raise_for_status ()
58+ content = response .content
59+ if not content :
60+ msg = f"Failed to download package: no content received from { url } "
61+ raise ValueError (msg )
7062
7163 logger .info ("Extracting %s to %s..." , name , dest_dir )
7264 dest_dir .mkdir (parents = True , exist_ok = True )
65+ _extract_tar (content , dest_dir )
66+
67+ logger .info ("Successfully vendored %s:%s" , name , version )
68+
69+
70+ def _extract_tar (content : bytes , dest_dir : Path ) -> None :
71+ """Extract a gzipped tarball while preventing directory traversal."""
7372 dest_abs = dest_dir .resolve ()
7473
7574 tar_data = io .BytesIO (content )
@@ -83,6 +82,3 @@ def download_package(
8382 msg = f"Attempted directory traversal in tarball: { member .name } "
8483 raise ValueError (msg )
8584 tar .extractall (path = dest_dir )
86-
87- logger .info ("Successfully vendored %s:%s" , name , version )
88- return True
0 commit comments