Merge branch '3.0'

This commit is contained in:
terrafrost 2024-08-19 07:00:10 -05:00
commit 394d15bf3a
2 changed files with 50 additions and 1 deletions

View File

@ -115,6 +115,7 @@ class SSH2
public const MASK_LOGIN_REQ = 0x00000004;
public const MASK_LOGIN = 0x00000008;
public const MASK_SHELL = 0x00000010;
public const MASK_DISCONNECT = 0x00000020;
/*
* Channel constants
@ -4249,7 +4250,12 @@ class SSH2
*/
protected function disconnect_helper(int $reason): bool
{
if ($this->bitmap & self::MASK_CONNECTED) {
if ($this->bitmap & self::MASK_DISCONNECT) {
// Disregard subsequent disconnect requests
return false;
}
$this->bitmap |= self::MASK_DISCONNECT;
if ($this->isConnected()) {
$data = Strings::packSSH2('CNss', MessageType::DISCONNECT, $reason, '', '');
try {
$this->send_binary_packet($data);

View File

@ -35,6 +35,24 @@ class SSH2UnitTest extends PhpseclibTestCase
];
}
/**
* @requires PHPUnit < 10
* Verify that MASK_* constants remain distinct
*/
public function testBitmapMasks(): void
{
$reflection = new \ReflectionClass(SSH2::class);
$masks = array_filter($reflection->getConstants(), function ($k) {
return str_starts_with($k, 'MASK_');
}, ARRAY_FILTER_USE_KEY);
$bitmap = 0;
foreach ($masks as $mask => $bit) {
$this->assertEquals(0, $bitmap & $bit, "Got unexpected mask {$mask}");
$bitmap |= $bit;
$this->assertEquals($bit, $bitmap & $bit, "Absent expected mask {$mask}");
}
}
/**
* @dataProvider formatLogDataProvider
* @requires PHPUnit < 10
@ -381,6 +399,31 @@ class SSH2UnitTest extends PhpseclibTestCase
self::callFunc($ssh, 'send_channel_packet', [1, 'hello world']);
}
/**
* @requires PHPUnit < 10
*/
public function testDisconnectHelper(): void
{
$ssh = $this->getMockBuilder('phpseclib3\Net\SSH2')
->disableOriginalConstructor()
->setMethods(['__destruct', 'isConnected', 'send_binary_packet'])
->getMock();
$ssh->expects($this->once())
->method('isConnected')
->willReturn(true);
$ssh->expects($this->once())
->method('send_binary_packet')
->with($this->isType('string'))
->willReturnCallback(function () use ($ssh): void {
self::callFunc($ssh, 'disconnect_helper', [1]);
throw new \Exception('catch me');
});
$this->assertEquals(0, self::getVar($ssh, 'bitmap'));
self::callFunc($ssh, 'disconnect_helper', [1]);
$this->assertEquals(0, self::getVar($ssh, 'bitmap'));
}
protected function createSSHMock(): SSH2
{
return $this->getMockBuilder('phpseclib3\Net\SSH2')