Skip to content

Commit f7ce82d

Browse files
committed
Add validation for committer name/email so we don't confuse fast-import; resolves #39
1 parent 7cff0cc commit f7ce82d

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

mike/git_utils.py

+19-4
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,12 @@ def __init__(self, branch, message):
153153
cmd = ['git', 'fast-import', '--date-format=raw', '--quiet', '--done']
154154
self._pipe = sp.Popen(cmd, stdin=sp.PIPE, stderr=sp.DEVNULL,
155155
universal_newlines=False)
156-
self._start_commit(branch, message)
157156
self._finished = False
157+
try:
158+
self._start_commit(branch, message)
159+
except Exception:
160+
self.abort()
161+
raise
158162

159163
def __enter__(self):
160164
return self
@@ -173,10 +177,18 @@ def _write(self, data):
173177

174178
def _start_commit(self, branch, message):
175179
name = get_config('user.name')
180+
if re.search(r'[<>\n]', name):
181+
raise GitError('invalid user.name: {!r}'.format(name))
182+
176183
email = get_config('user.email')
184+
if not email:
185+
raise GitError('user.email is not set')
186+
if re.search(r'[<>\n]', email):
187+
raise GitError('invalid user.email: {!r}'.format(email))
188+
177189
self._write('commit refs/heads/{}\n'.format(branch))
178-
self._write('committer {name} <{email}> {time}\n'.format(
179-
name=name, email=email, time=make_when()
190+
self._write('committer {name}<{email}> {time}\n'.format(
191+
name=name + ' ' if name else '', email=email, time=make_when()
180192
))
181193
self._write('data {length}\n{message}\n'.format(
182194
length=len(message), message=message
@@ -217,7 +229,10 @@ def abort(self):
217229
raise GitError('commit already finalized')
218230
self._finished = True
219231

220-
self._pipe.stdin.close()
232+
try:
233+
self._pipe.stdin.close()
234+
except BrokenPipeError: # pragma: no cover
235+
pass
221236
self._pipe.terminate()
222237
self._pipe.wait()
223238

test/unit/test_git_utils.py

+18
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
import sys
33
import unittest
4+
from unittest import mock
45

56
from .. import *
67
from mike import git_utils
@@ -340,6 +341,23 @@ def test_handle_exception(self):
340341
check_call_silent(['git', 'checkout', 'master'])
341342
assertDirectory('.', {'file.txt'})
342343

344+
def test_invalid_username(self):
345+
check_call_silent(['git', 'config', 'user.name', '<>'])
346+
with self.assertRaises(git_utils.GitError):
347+
with git_utils.Commit('master', 'add file'):
348+
pass
349+
350+
def test_invalid_email(self):
351+
check_call_silent(['git', 'config', 'user.email', '<>'])
352+
with self.assertRaises(git_utils.GitError):
353+
with git_utils.Commit('master', 'add file'):
354+
pass
355+
356+
with mock.patch('mike.git_utils.get_config', return_value=''), \
357+
self.assertRaises(git_utils.GitError):
358+
with git_utils.Commit('master', 'add file'):
359+
pass
360+
343361

344362
class TestPushBranch(unittest.TestCase):
345363
def setUp(self):

0 commit comments

Comments
 (0)