Skip to content

Commit ffddedf

Browse files
committed
Use copy and not inplace remove password + working case test
1 parent 50cbafc commit ffddedf

File tree

4 files changed

+21
-13
lines changed

4 files changed

+21
-13
lines changed

git/cmd.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ def read_all_from_possibly_closed_stream(stream):
405405
if status != 0:
406406
errstr = read_all_from_possibly_closed_stream(self.proc.stderr)
407407
log.debug('AutoInterrupt wait stderr: %r' % (errstr,))
408-
raise GitCommandError(self.args, status, errstr)
408+
raise GitCommandError(remove_password_if_present(self.args), status, errstr)
409409
# END status handling
410410
return status
411411
# END auto interrupt
@@ -638,7 +638,7 @@ def execute(self, command,
638638
639639
:param env:
640640
A dictionary of environment variables to be passed to `subprocess.Popen`.
641-
641+
642642
:param max_chunk_size:
643643
Maximum number of bytes in one chunk of data passed to the output_stream in
644644
one invocation of write() method. If the given number is not positive then
@@ -706,7 +706,7 @@ def execute(self, command,
706706
if is_win:
707707
cmd_not_found_exception = OSError
708708
if kill_after_timeout:
709-
raise GitCommandError(command, '"kill_after_timeout" feature is not supported on Windows.')
709+
raise GitCommandError(redacted_command, '"kill_after_timeout" feature is not supported on Windows.')
710710
else:
711711
if sys.version_info[0] > 2:
712712
cmd_not_found_exception = FileNotFoundError # NOQA # exists, flake8 unknown @UndefinedVariable
@@ -721,7 +721,7 @@ def execute(self, command,
721721
if istream:
722722
istream_ok = "<valid stream>"
723723
log.debug("Popen(%s, cwd=%s, universal_newlines=%s, shell=%s, istream=%s)",
724-
command, cwd, universal_newlines, shell, istream_ok)
724+
redacted_command, cwd, universal_newlines, shell, istream_ok)
725725
try:
726726
proc = Popen(command,
727727
env=env,
@@ -737,7 +737,7 @@ def execute(self, command,
737737
**subprocess_kwargs
738738
)
739739
except cmd_not_found_exception as err:
740-
raise GitCommandNotFound(command, err) from err
740+
raise GitCommandNotFound(redacted_command, err) from err
741741

742742
if as_process:
743743
return self.AutoInterrupt(proc, command)
@@ -787,7 +787,7 @@ def _kill_process(pid):
787787
watchdog.cancel()
788788
if kill_check.isSet():
789789
stderr_value = ('Timeout: the command "%s" did not complete in %d '
790-
'secs.' % (" ".join(command), kill_after_timeout))
790+
'secs.' % (" ".join(redacted_command), kill_after_timeout))
791791
if not universal_newlines:
792792
stderr_value = stderr_value.encode(defenc)
793793
# strip trailing "\n"
@@ -811,7 +811,7 @@ def _kill_process(pid):
811811
proc.stderr.close()
812812

813813
if self.GIT_PYTHON_TRACE == 'full':
814-
cmdstr = " ".join(command)
814+
cmdstr = " ".join(redacted_command)
815815

816816
def as_text(stdout_value):
817817
return not output_stream and safe_decode(stdout_value) or '<OUTPUT_STREAM>'
@@ -827,7 +827,7 @@ def as_text(stdout_value):
827827
# END handle debug printing
828828

829829
if with_exceptions and status != 0:
830-
raise GitCommandError(command, status, stderr_value, stdout_value)
830+
raise GitCommandError(redacted_command, status, stderr_value, stdout_value)
831831

832832
if isinstance(stdout_value, bytes) and stdout_as_string: # could also be output_stream
833833
stdout_value = safe_decode(stdout_value)

git/util.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,9 @@ def remove_password_if_present(cmdline):
349349
350350
This should be used for every log line that print a command line.
351351
"""
352+
new_cmdline = []
352353
for index, to_parse in enumerate(cmdline):
354+
new_cmdline.append(to_parse)
353355
try:
354356
url = urlsplit(to_parse)
355357
# Remove password from the URL if present
@@ -358,11 +360,11 @@ def remove_password_if_present(cmdline):
358360

359361
edited_url = url._replace(
360362
netloc=url.netloc.replace(url.password, "*****"))
361-
cmdline[index] = urlunsplit(edited_url)
363+
new_cmdline[index] = urlunsplit(edited_url)
362364
except ValueError:
363365
# This is not a valid URL
364366
pass
365-
return cmdline
367+
return new_cmdline
366368

367369

368370
#} END utilities

test/test_repo.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,6 @@ def test_clone_from_with_path_contains_unicode(self):
240240

241241
@with_rw_directory
242242
def test_leaking_password_in_clone_logs(self, rw_dir):
243-
"""Check that the password is not printed on the logs"""
244243
password = "fakepassword1234"
245244
try:
246245
Repo.clone_from(
@@ -249,6 +248,10 @@ def test_leaking_password_in_clone_logs(self, rw_dir):
249248
to_path=rw_dir)
250249
except GitCommandError as err:
251250
assert password not in str(err), "The error message '%s' should not contain the password" % err
251+
# Working example from a blank private project
252+
Repo.clone_from(
253+
url="https://gitlab+deploy-token-392045:mLWhVus7bjLsy8xj8q2V@gitlab.com/mercierm/test_git_python",
254+
to_path=rw_dir)
252255

253256
@with_rw_repo('HEAD')
254257
def test_max_chunk_size(self, repo):

test/test_util.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,6 @@ def test_pickle_tzoffset(self):
325325
self.assertEqual(t1._name, t2._name)
326326

327327
def test_remove_password_from_command_line(self):
328-
"""Check that the password is not printed on the logs"""
329328
password = "fakepassword1234"
330329
url_with_pass = "https://fakeuser:{}@fakerepo.example.com/testrepo".format(password)
331330
url_without_pass = "https://fakerepo.example.com/testrepo"
@@ -334,6 +333,10 @@ def test_remove_password_from_command_line(self):
334333
cmd_2 = ["git", "clone", "-v", url_without_pass]
335334
cmd_3 = ["no", "url", "in", "this", "one"]
336335

337-
assert password not in remove_password_if_present(cmd_1)
336+
redacted_cmd_1 = remove_password_if_present(cmd_1)
337+
assert password not in " ".join(redacted_cmd_1)
338+
# Check that we use a copy
339+
assert cmd_1 is not redacted_cmd_1
340+
assert password in " ".join(cmd_1)
338341
assert cmd_2 == remove_password_if_present(cmd_2)
339342
assert cmd_3 == remove_password_if_present(cmd_3)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy