Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/Gitonomy/Git/Util/Credentials.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ public static function redact(#[\SensitiveParameter] string $text): string
{
// Up to the last "@" before the host, as a password may hold one, or a
// "#" or a "?", which git and libgit2 accept unencoded there.
// Without a scheme too: git prints "user:token@host" when it can't
// resolve the host of a git:// URL. A token alone stays, as nothing
// tells it from the "git@host" of the errors of ssh.
// @phpstan-ignore return.type (possessive quantifiers never reach the backtracking limit, and without "u" there is no UTF-8 to fail on)
return preg_replace('#\b([a-z][a-z0-9+.-]*+://)(?:[^/\s@]*+@)++#i', '$1***@', $text);
return preg_replace('#(?:\b([a-z][a-z0-9+.-]*+://)|(?<!\S)[^/\s@:]++:)(?:[^/\s@]*+@)++#i', '$1***@', $text);
}
}
6 changes: 6 additions & 0 deletions tests/Gitonomy/Git/Tests/CredentialsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,13 @@ public static function provideTexts(): iterable
yield 'password holding a "?"' => ['https://***@example.com/a.git', 'https://user:[email protected]/a.git'];
yield 'several URLs' => ['ssh://***@a.com/x and https://***@b.com/y', 'ssh://[email protected]/x and https://user:[email protected]/y'];
yield 'no user information' => ['https://example.com/[email protected]', 'https://example.com/[email protected]'];
yield 'no user information, with a port' => ['https://example.com:8080/[email protected]', 'https://example.com:8080/[email protected]'];
yield 'no scheme' => ['[email protected]:a.git', '[email protected]:a.git'];
yield 'no scheme, the error of ssh' => ['[email protected]: Permission denied (publickey).', '[email protected]: Permission denied (publickey).'];
yield 'no scheme, an address after a label' => ['Author: [email protected]', 'Author: [email protected]'];
yield 'no scheme, the host git prints for a git:// URL' => ['fatal: unable to look up ***@example.com (port 9418)', 'fatal: unable to look up user:[email protected] (port 9418)'];
yield 'no scheme, with a port' => ['unable to look up ***@example.com:9418', 'unable to look up user:[email protected]:9418'];
yield 'no scheme, password holding an "@"' => ['unable to look up ***@example.com', 'unable to look up user:p@[email protected]'];
}

/**
Expand Down