2828 exec (f .read (), about )
2929
3030class sdist (sdist_orig ):
31- """
32- Subclass sdist so that we can download all standalone ruby applications
33- into ./pact/bin so our users receive all the binaries on pip install.
34- """
31+ """Subclass sdist to download all standalone ruby applications into ./pact/bin."""
32+
3533 def run (self ):
34+ """Installs the dist."""
3635 package_bin_path = os .path .join (os .path .dirname (__file__ ), 'pact' , 'bin' )
3736
3837 if os .path .exists (package_bin_path ):
@@ -79,12 +78,12 @@ class PactPythonInstallCommand(install):
7978 user_options = install .user_options + [('bin-path=' , None , None )]
8079
8180 def initialize_options (self ):
82- """Load our preconfigured options"""
81+ """Load our preconfigured options. """
8382 install .initialize_options (self )
8483 self .bin_path = None
8584
8685 def finalize_options (self ):
87- """Load provided CLI arguments into our options"""
86+ """Load provided CLI arguments into our options. """
8887 install .finalize_options (self )
8988
9089 def run (self ):
@@ -124,7 +123,7 @@ def install_ruby_app(package_bin_path: str, download_bin_path=None):
124123
125124def ruby_app_binary ():
126125 """
127- Determines the ruby app binary required for this OS.
126+ Determine the ruby app binary required for this OS.
128127
129128 :return A dictionary of type {'filename': string, 'version': string, 'suffix': string }
130129 """
@@ -151,7 +150,7 @@ def ruby_app_binary():
151150
152151def download_ruby_app_binary (path_to_download_to , filename , suffix ):
153152 """
154- Downloads `binary` into `path_to_download_to`.
153+ Download `binary` into `path_to_download_to`.
155154
156155 :param path_to_download_to: The path where binaries should be downloaded.
157156 :param filename: The filename that should be installed.
@@ -177,7 +176,7 @@ def download_ruby_app_binary(path_to_download_to, filename, suffix):
177176
178177def extract_ruby_app_binary (source , destination , binary ):
179178 """
180- Extracts the ruby app binary from `source` into `destination`.
179+ Extract the ruby app binary from `source` into `destination`.
181180
182181 :param source: The location of the binary to unarchive.
183182 :param destination: The location to unarchive to.
@@ -189,8 +188,25 @@ def extract_ruby_app_binary(source, destination, binary):
189188 f .extractall (destination )
190189 else :
191190 with tarfile .open (path ) as f :
192- f .extractall (destination )
191+ def is_within_directory (directory , target ):
192+
193+ abs_directory = os .path .abspath (directory )
194+ abs_target = os .path .abspath (target )
195+
196+ prefix = os .path .commonprefix ([abs_directory , abs_target ])
197+
198+ return prefix == abs_directory
199+
200+ def safe_extract (tar , path = "." , members = None , * , numeric_owner = False ):
201+
202+ for member in tar .getmembers ():
203+ member_path = os .path .join (path , member .name )
204+ if not is_within_directory (path , member_path ):
205+ raise Exception ("Attempted Path Traversal in Tar File" )
206+
207+ tar .extractall (path , members , numeric_owner = numeric_owner )
193208
209+ safe_extract (f , destination )
194210
195211def read (filename ):
196212 """Read file contents."""
@@ -200,13 +216,14 @@ def read(filename):
200216
201217
202218dependencies = [
203- 'click>=2.0.0 ' ,
204- 'psutil>=2.0.0 ' ,
205- 'requests>=2.26 .0' ,
206- 'six>=1.9 .0' ,
219+ 'click>=8.1.3 ' ,
220+ 'psutil>=5.9.4 ' ,
221+ 'requests>=2.28 .0' ,
222+ 'six>=1.16 .0' ,
207223 'fastapi>=0.67.0' ,
208- 'urllib3>=1.26.5' ,
209- 'uvicorn>=0.14.0'
224+ 'urllib3>=1.26.12' ,
225+ 'uvicorn>=0.19.0' ,
226+ 'httpx==0.23.1'
210227]
211228
212229if __name__ == '__main__' :
0 commit comments