Encode URI credentials when rebuilding subscription authority
This commit is contained in:
parent
8f7a40208f
commit
af3efe5bcd
@ -78,7 +78,8 @@ final class Codec
|
||||
throw new InvalidArgumentException('missing_auth');
|
||||
}
|
||||
// Rebuild only authority. Keep query bytes intact: do not decode the whole URI.
|
||||
$authority = ($url['user'] ?? '').(isset($url['pass']) ? ':'.$url['pass'] : '');
|
||||
// Percent-encode decoded userinfo once; raw brackets belong to credentials, not IPv6.
|
||||
$authority = rawurlencode($user).(isset($url['pass']) ? ':'.rawurlencode($password) : '');
|
||||
$authority = ($authority !== '' ? $authority.'@' : '').(str_contains($host, ':') ? '['.$host.']' : $host).':'.$port;
|
||||
$connection = $authority.($url['path'] ?? '').(isset($url['query']) ? '?'.$url['query'] : '');
|
||||
return self::node($type, ['host' => $host, 'port' => $port, 'user' => $user, 'password' => $password, 'query' => $query, 'connection' => $connection], rawurldecode($name));
|
||||
|
||||
@ -41,6 +41,32 @@ final class CodecTest extends TestCase
|
||||
self::assertSame('a+b@c#d', Codec::singbox($node, 'x')['password']);
|
||||
}
|
||||
|
||||
public function testRawPasswordBracketsAreEscapedInPublishedUri(): void
|
||||
{
|
||||
$node = Codec::parse('trojan://pass[word]@example.invalid:443?security=tls#test');
|
||||
$uri = Codec::uri($node, 'test');
|
||||
self::assertStringStartsWith('trojan://pass%5Bword%5D@example.invalid:443?', $uri);
|
||||
self::assertSame('pass[word]', Codec::singbox($node, 'test')['password']);
|
||||
self::assertSame($node['id'], Codec::parse($uri)['id']);
|
||||
}
|
||||
|
||||
public function testEscapedUserinfoKeepsExactDecodedPassword(): void
|
||||
{
|
||||
$password = 'a[b]+c@d#e:f%2F';
|
||||
$node = Codec::parse('trojan://'.rawurlencode($password).'@example.invalid:443?security=tls#test');
|
||||
$uri = Codec::uri($node, 'test');
|
||||
self::assertStringStartsWith('trojan://'.rawurlencode($password).'@', $uri);
|
||||
self::assertSame($password, Codec::singbox(Codec::parse($uri), 'test')['password']);
|
||||
self::assertSame($node['id'], Codec::parse($uri)['id']);
|
||||
}
|
||||
|
||||
public function testPasswordBracketsDoNotChangeIpv6Host(): void
|
||||
{
|
||||
$node = Codec::parse('trojan://a[b]@[2001:db8::1]:443?security=tls#test');
|
||||
self::assertStringStartsWith('trojan://a%5Bb%5D@[2001:db8::1]:443?', Codec::uri($node, 'test'));
|
||||
self::assertSame('2001:db8::1', Codec::singbox($node, 'test')['server']);
|
||||
}
|
||||
|
||||
public function testSsBase64UrlAndPlugin(): void
|
||||
{
|
||||
$auth = rtrim(strtr(base64_encode('aes-128-gcm:a+b'), '+/', '-_'), '=');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user