|
13 | 13 | importpickle
|
14 | 14 | importsys
|
15 | 15 | importtempfile
|
16 |
| -importuuid |
17 | 16 | fromunittestimportmock,skipIf,SkipTest
|
18 | 17 |
|
19 | 18 | importpytest
|
@@ -226,6 +225,7 @@ def test_clone_from_pathlib_withConfig(self, rw_dir):
|
226 | 225 | "--config submodule.repo.update=checkout",
|
227 | 226 | "--config filter.lfs.clean='git-lfs clean -- %f'",
|
228 | 227 | ],
|
| 228 | +allow_unsafe_options=True, |
229 | 229 | )
|
230 | 230 |
|
231 | 231 | self.assertEqual(cloned.config_reader().get_value("submodule","active"),"repo")
|
@@ -266,39 +266,133 @@ def test_leaking_password_in_clone_logs(self, rw_dir):
|
266 | 266 | to_path=rw_dir,
|
267 | 267 | )
|
268 | 268 |
|
269 |
| -deftest_unsafe_options(self): |
270 |
| -self.assertFalse(Repo.unsafe_options("github.com/deploy/deploy")) |
| 269 | +@with_rw_repo("HEAD") |
| 270 | +deftest_clone_unsafe_options(self,rw_repo): |
| 271 | +tmp_dir=pathlib.Path(tempfile.mkdtemp()) |
| 272 | +tmp_file=tmp_dir/"pwn" |
| 273 | +unsafe_options= [ |
| 274 | +f"--upload-pack='touch{tmp_file}'", |
| 275 | +f"-u 'touch{tmp_file}'", |
| 276 | +"--config=protocol.ext.allow=always", |
| 277 | +"-c protocol.ext.allow=always", |
| 278 | + ] |
| 279 | +forunsafe_optioninunsafe_options: |
| 280 | +withself.assertRaises(UnsafeOptionError): |
| 281 | +rw_repo.clone(tmp_dir,multi_options=[unsafe_option]) |
271 | 282 |
|
272 |
| -deftest_unsafe_options_ext_url(self): |
273 |
| -self.assertTrue(Repo.unsafe_options("ext::ssh")) |
| 283 | +@with_rw_repo("HEAD") |
| 284 | +deftest_clone_unsafe_options_allowed(self,rw_repo): |
| 285 | +tmp_dir=pathlib.Path(tempfile.mkdtemp()) |
| 286 | +tmp_file=tmp_dir/"pwn" |
| 287 | +unsafe_options= [ |
| 288 | +f"--upload-pack='touch{tmp_file}'", |
| 289 | +f"-u 'touch{tmp_file}'", |
| 290 | + ] |
| 291 | +fori,unsafe_optioninenumerate(unsafe_options): |
| 292 | +destination=tmp_dir/str(i) |
| 293 | +# The options will be allowed, but the command will fail. |
| 294 | +withself.assertRaises(GitCommandError): |
| 295 | +rw_repo.clone(destination,multi_options=[unsafe_option],allow_unsafe_options=True) |
| 296 | + |
| 297 | +unsafe_options= [ |
| 298 | +"--config=protocol.ext.allow=always", |
| 299 | +"-c protocol.ext.allow=always", |
| 300 | + ] |
| 301 | +fori,unsafe_optioninenumerate(unsafe_options): |
| 302 | +destination=tmp_dir/str(i) |
| 303 | +assertnotdestination.exists() |
| 304 | +rw_repo.clone(destination,multi_options=[unsafe_option],allow_unsafe_options=True) |
| 305 | +assertdestination.exists() |
274 | 306 |
|
275 |
| -deftest_unsafe_options_multi_options_upload_pack(self): |
276 |
| -self.assertTrue(Repo.unsafe_options("", ["--upload-pack='touch foo'"])) |
| 307 | +@with_rw_repo("HEAD") |
| 308 | +deftest_clone_safe_options(self,rw_repo): |
| 309 | +tmp_dir=pathlib.Path(tempfile.mkdtemp()) |
| 310 | +options= [ |
| 311 | +"--depth=1", |
| 312 | +"--single-branch", |
| 313 | +"-q", |
| 314 | + ] |
| 315 | +foroptioninoptions: |
| 316 | +destination=tmp_dir/option |
| 317 | +assertnotdestination.exists() |
| 318 | +rw_repo.clone(destination,multi_options=[option]) |
| 319 | +assertdestination.exists() |
277 | 320 |
|
278 |
| -deftest_unsafe_options_multi_options_config_user(self): |
279 |
| -self.assertFalse(Repo.unsafe_options("", ["--config user"])) |
| 321 | +@with_rw_repo("HEAD") |
| 322 | +deftest_clone_from_unsafe_options(self,rw_repo): |
| 323 | +tmp_dir=pathlib.Path(tempfile.mkdtemp()) |
| 324 | +tmp_file=tmp_dir/"pwn" |
| 325 | +unsafe_options= [ |
| 326 | +f"--upload-pack='touch{tmp_file}'", |
| 327 | +f"-u 'touch{tmp_file}'", |
| 328 | +"--config=protocol.ext.allow=always", |
| 329 | +"-c protocol.ext.allow=always", |
| 330 | + ] |
| 331 | +forunsafe_optioninunsafe_options: |
| 332 | +withself.assertRaises(UnsafeOptionError): |
| 333 | +Repo.clone_from(rw_repo.working_dir,tmp_dir,multi_options=[unsafe_option]) |
280 | 334 |
|
281 |
| -deftest_unsafe_options_multi_options_config_protocol(self): |
282 |
| -self.assertTrue(Repo.unsafe_options("", ["--config protocol.foo"])) |
| 335 | +@with_rw_repo("HEAD") |
| 336 | +deftest_clone_from_unsafe_options_allowed(self,rw_repo): |
| 337 | +tmp_dir=pathlib.Path(tempfile.mkdtemp()) |
| 338 | +tmp_file=tmp_dir/"pwn" |
| 339 | +unsafe_options= [ |
| 340 | +f"--upload-pack='touch{tmp_file}'", |
| 341 | +f"-u 'touch{tmp_file}'", |
| 342 | + ] |
| 343 | +fori,unsafe_optioninenumerate(unsafe_options): |
| 344 | +destination=tmp_dir/str(i) |
| 345 | +# The options will be allowed, but the command will fail. |
| 346 | +withself.assertRaises(GitCommandError): |
| 347 | +Repo.clone_from( |
| 348 | +rw_repo.working_dir,destination,multi_options=[unsafe_option],allow_unsafe_options=True |
| 349 | + ) |
283 | 350 |
|
284 |
| -deftest_clone_from_forbids_helper_urls_by_default(self): |
285 |
| -withself.assertRaises(UnsafeOptionError): |
286 |
| -Repo.clone_from("ext::sh -c touch% /tmp/foo","tmp") |
| 351 | +unsafe_options= [ |
| 352 | +"--config=protocol.ext.allow=always", |
| 353 | +"-c protocol.ext.allow=always", |
| 354 | + ] |
| 355 | +fori,unsafe_optioninenumerate(unsafe_options): |
| 356 | +destination=tmp_dir/str(i) |
| 357 | +assertnotdestination.exists() |
| 358 | +Repo.clone_from(rw_repo.working_dir,destination,multi_options=[unsafe_option],allow_unsafe_options=True) |
| 359 | +assertdestination.exists() |
287 | 360 |
|
288 | 361 | @with_rw_repo("HEAD")
|
289 |
| -deftest_clone_from_allow_unsafe(self,repo): |
290 |
| -bad_filename=pathlib.Path(f'{tempfile.gettempdir()}/{uuid.uuid4()}') |
291 |
| -bad_url=f'ext::sh -c touch%{bad_filename}' |
292 |
| -try: |
293 |
| -repo.clone_from( |
294 |
| -bad_url,'tmp', |
295 |
| -multi_options=["-c protocol.ext.allow=always"], |
296 |
| -unsafe_protocols=True |
297 |
| - ) |
298 |
| -exceptGitCommandError: |
299 |
| -pass |
300 |
| -self.assertTrue(bad_filename.is_file()) |
301 |
| -bad_filename.unlink() |
| 362 | +deftest_clone_from_safe_options(self,rw_repo): |
| 363 | +tmp_dir=pathlib.Path(tempfile.mkdtemp()) |
| 364 | +options= [ |
| 365 | +"--depth=1", |
| 366 | +"--single-branch", |
| 367 | +"-q", |
| 368 | + ] |
| 369 | +foroptioninoptions: |
| 370 | +destination=tmp_dir/option |
| 371 | +assertnotdestination.exists() |
| 372 | +Repo.clone_from(rw_repo.common_dir,destination,multi_options=[option]) |
| 373 | +assertdestination.exists() |
| 374 | + |
| 375 | +deftest_clone_from_unsafe_procol(self): |
| 376 | +tmp_dir=pathlib.Path(tempfile.mkdtemp()) |
| 377 | +urls= [ |
| 378 | +"ext::sh -c touch% /tmp/pwn", |
| 379 | +"fd::17/foo", |
| 380 | + ] |
| 381 | +forurlinurls: |
| 382 | +withself.assertRaises(UnsafeProtocolError): |
| 383 | +Repo.clone_from(url,tmp_dir) |
| 384 | + |
| 385 | +deftest_clone_from_unsafe_procol_allowed(self): |
| 386 | +tmp_dir=pathlib.Path(tempfile.mkdtemp()) |
| 387 | +urls= [ |
| 388 | +"ext::sh -c touch% /tmp/pwn", |
| 389 | +"fd::/foo", |
| 390 | + ] |
| 391 | +forurlinurls: |
| 392 | +# The URL will be allowed into the command, but the command will |
| 393 | +# fail since we don't have that protocol enabled in the Git config file. |
| 394 | +withself.assertRaises(GitCommandError): |
| 395 | +Repo.clone_from(url,tmp_dir,allow_unsafe_protocols=True) |
302 | 396 |
|
303 | 397 | @with_rw_repo("HEAD")
|
304 | 398 | deftest_max_chunk_size(self,repo):
|
|