mirror of
https://github.com/Vateron-Media/XC_VM.git
synced 2026-10-03 20:02:29 +02:00
The panel boots the DB with `new DatabaseHandler()` and no arguments, so $host is null and the real credentials are resolved by the bundled XC_VM extension in db_connect() — dbhost is never used on that path. A strict `normalizeHost(string $rHost)` hint turned that normal null into a fatal TypeError at bootstrap (initDatabase → __construct → normalizeHost), taking down console.php / cron boot: Database::normalizeHost(): Argument #1 ($rHost) must be of type string, null given, called in .../Database.php on line 53 Make normalizeHost accept and pass through null (?string → ?string), restoring the pre-typing behaviour; the explicit-credentials path (db_explicit_connect) still passes a real string. Also make the constructor's implicitly-nullable `string $x = null` params explicitly `?string` (same root cause, no behaviour change, and avoids the PHP 8.4 implicit-nullable deprecation). Add DatabaseHostTest as a regression (reflection on a constructor-less instance, since the class needs the XC_VM extension to instantiate).
43 lines
1.5 KiB
PHP
43 lines
1.5 KiB
PHP
<?php
|
|
|
|
use XcVm\Core\Database\Database;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
/**
|
|
* Database::normalizeHost — regression for a production CLI-boot crash.
|
|
*
|
|
* The panel constructs `new DatabaseHandler()` with no arguments, so $host is
|
|
* null and the real credentials are resolved by the bundled XC_VM extension in
|
|
* db_connect(). A strict `normalizeHost(string $rHost)` hint made that null a
|
|
* fatal TypeError at boot; the parameter must accept null and pass it through.
|
|
*
|
|
* The class can't be instantiated here (db_connect() needs the XC_VM
|
|
* extension), so the private method is exercised on a constructor-less instance
|
|
* via reflection.
|
|
*/
|
|
final class DatabaseHostTest extends TestCase {
|
|
|
|
private function normalize(?string $host)
|
|
{
|
|
$instance = (new ReflectionClass(Database::class))->newInstanceWithoutConstructor();
|
|
$method = new ReflectionMethod(Database::class, 'normalizeHost');
|
|
$method->setAccessible(true);
|
|
return $method->invoke($instance, $host);
|
|
}
|
|
|
|
public function testNullHostPassesThroughInsteadOfThrowing(): void {
|
|
// Regression: a null host (the no-arg DatabaseHandler() boot path) must
|
|
// not raise a TypeError.
|
|
$this->assertNull($this->normalize(null));
|
|
}
|
|
|
|
public function testLocalhostIsForcedToTcpLoopback(): void {
|
|
$this->assertSame('127.0.0.1', $this->normalize('localhost'));
|
|
}
|
|
|
|
public function testOtherHostsAreUnchanged(): void {
|
|
$this->assertSame('db.internal', $this->normalize('db.internal'));
|
|
$this->assertSame('10.0.0.5', $this->normalize('10.0.0.5'));
|
|
}
|
|
}
|