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:p?ss@example.com/a.git'];
yield 'several URLs' => ['ssh://***@a.com/x and https://***@b.com/y', 'ssh://git@a.com/x and https://user:password@b.com/y'];
yield 'no user information' => ['https://example.com/a@b.git', 'https://example.com/a@b.git'];
yield 'no user information, with a port' => ['https://example.com:8080/a@b.git', 'https://example.com:8080/a@b.git'];
yield 'no scheme' => ['git@example.com:a.git', 'git@example.com:a.git'];
yield 'no scheme, the error of ssh' => ['git@example.com: Permission denied (publickey).', 'git@example.com: Permission denied (publickey).'];
yield 'no scheme, an address after a label' => ['Author: jane@example.com', 'Author: jane@example.com'];
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:password@example.com (port 9418)'];
yield 'no scheme, with a port' => ['unable to look up ***@example.com:9418', 'unable to look up user:password@example.com:9418'];
yield 'no scheme, password holding an "@"' => ['unable to look up ***@example.com', 'unable to look up user:p@ss@example.com'];
}

/**
Expand Down