Skip to content

Commit

Permalink
Merge pull request #1689 from cookiecutter/sanitize-mercurial-checkout
Browse files Browse the repository at this point in the history
Sanitize Mercurial branch information before checkout.
  • Loading branch information
jensens committed Jun 1, 2022
2 parents 94036d0 + 85a7884 commit fdffddb
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 10 deletions.
2 changes: 2 additions & 0 deletions HISTORY.md
Expand Up @@ -2,6 +2,8 @@

History is important, but our current roadmap can be found [here](https://github.com/cookiecutter/cookiecutter/projects)

## 2.1.1 (unreleased)

## 2.1.0 (2022-05-30)

### Changes
Expand Down
14 changes: 9 additions & 5 deletions cookiecutter/vcs.py
Expand Up @@ -98,22 +98,26 @@ def clone(repo_url, checkout=None, clone_to_dir='.', no_input=False):
stderr=subprocess.STDOUT,
)
if checkout is not None:
checkout_params = [checkout]
# Avoid Mercurial "--config" and "--debugger" injection vulnerability
if repo_type == "hg":
checkout_params.insert(0, "--")
subprocess.check_output( # nosec
[repo_type, 'checkout', checkout],
[repo_type, 'checkout', *checkout_params],
cwd=repo_dir,
stderr=subprocess.STDOUT,
)
except subprocess.CalledProcessError as clone_error:
output = clone_error.output.decode('utf-8')
if 'not found' in output.lower():
raise RepositoryNotFound(
'The repository {} could not be found, '
'have you made a typo?'.format(repo_url)
f'The repository {repo_url} could not be found, '
'have you made a typo?'
)
if any(error in output for error in BRANCH_ERRORS):
raise RepositoryCloneFailed(
'The {} branch of repository {} could not found, '
'have you made a typo?'.format(checkout, repo_url)
f'The {checkout} branch of repository '
f'{repo_url} could not found, have you made a typo?'
)
logger.error('git clone failed with error: %s', output)
raise
Expand Down
18 changes: 13 additions & 5 deletions tests/vcs/test_clone.py
Expand Up @@ -122,8 +122,16 @@ def test_clone_should_invoke_vcs_command(
mock_subprocess.assert_any_call(
[repo_type, 'clone', repo_url], cwd=str(clone_dir), stderr=subprocess.STDOUT
)

branch_info = [branch]
# We sanitize branch information for Mercurial
if repo_type == "hg":
branch_info.insert(0, "--")

mock_subprocess.assert_any_call(
[repo_type, 'checkout', branch], cwd=expected_repo_dir, stderr=subprocess.STDOUT
[repo_type, 'checkout', *branch_info],
cwd=expected_repo_dir,
stderr=subprocess.STDOUT,
)


Expand Down Expand Up @@ -151,8 +159,8 @@ def test_clone_handles_repo_typo(mocker, clone_dir, error_message):
vcs.clone(repository_url, clone_to_dir=str(clone_dir), no_input=True)

assert str(err.value) == (
'The repository {} could not be found, have you made a typo?'
).format(repository_url)
f'The repository {repository_url} could not be found, have you made a typo?'
)


@pytest.mark.parametrize(
Expand Down Expand Up @@ -182,8 +190,8 @@ def test_clone_handles_branch_typo(mocker, clone_dir, error_message):

assert str(err.value) == (
'The unknown_branch branch of repository '
'{} could not found, have you made a typo?'
).format(repository_url)
f'{repository_url} could not found, have you made a typo?'
)


def test_clone_unknown_subprocess_error(mocker, clone_dir):
Expand Down

0 comments on commit fdffddb

Please sign in to comment.