diff --git a/src/Appwrite/Platform/Installer/Runtime/State.php b/src/Appwrite/Platform/Installer/Runtime/State.php index 068bc9ca2e..5200232bdc 100644 --- a/src/Appwrite/Platform/Installer/Runtime/State.php +++ b/src/Appwrite/Platform/Installer/Runtime/State.php @@ -6,6 +6,12 @@ use Appwrite\Platform\Installer\Server; class State { + private const string PATTERN_DIGITS_ONLY = '/^\d+$/'; + private const string PATTERN_HAS_NON_WHITESPACE = '/\S/'; + private const string PATTERN_LINE_BREAKS = '/\r\n|\n|\r/'; + private const string PATTERN_INSTALL_ID_SANITIZE = '/[^a-zA-Z0-9_-]/'; + private const string PATTERN_IPV6_WITH_PORT = '/^\[(.+)](?::(\d+))?$/'; + private array $paths; private bool $bootstrapped = false; @@ -106,7 +112,7 @@ class State return ''; } - $clean = preg_replace('/[^a-zA-Z0-9_-]/', '', $value); + $clean = preg_replace(self::PATTERN_INSTALL_ID_SANITIZE, '', $value); if (!is_string($clean)) { return ''; } @@ -126,7 +132,7 @@ class State public function isValidPort($value): bool { $string = (string) $value; - if ($string === '' || !preg_match('/^\d+$/', $string)) { + if ($string === '' || !preg_match(self::PATTERN_DIGITS_ONLY, $string)) { return false; } $port = (int) $string; @@ -140,7 +146,7 @@ class State public function isValidPassword(string $value): bool { - return strlen($value) >= 8 && preg_match('/\S/', $value) === 1; + return strlen($value) >= 8 && preg_match(self::PATTERN_HAS_NON_WHITESPACE, $value) === 1; } public function isValidSecretKey(string $value): bool @@ -164,7 +170,7 @@ class State $port = null; if (str_starts_with($value, '[')) { - if (!preg_match('/^\[(.+)\](?::(\d+))?$/', $value, $matches)) { + if (!preg_match(self::PATTERN_IPV6_WITH_PORT, $value, $matches)) { return false; } $host = $matches[1] ?? ''; @@ -304,7 +310,7 @@ class State private function parseEnvFile(string $contents): array { $vars = []; - foreach ((array) preg_split('/\r\n|\n|\r/', $contents) as $line) { + foreach ((array) preg_split(self::PATTERN_LINE_BREAKS, $contents) as $line) { $line = trim($line); if ($line === '' || $line[0] === '#') { continue; diff --git a/src/Appwrite/Platform/Installer/Server.php b/src/Appwrite/Platform/Installer/Server.php index 0a29a84ed0..a5ec058570 100644 --- a/src/Appwrite/Platform/Installer/Server.php +++ b/src/Appwrite/Platform/Installer/Server.php @@ -30,6 +30,7 @@ class Server private const string DEFAULT_IMAGE = 'appwrite-dev'; public const string DEFAULT_CONTAINER = 'appwrite-installer'; + private const string PATTERN_SERVER_LOG_FILTER = '/]\s+\S+:\d+\s+(Accepted|Closing)/'; private const string DEV_SERVER_START_PATTERN = '/PHP\s+\d+\.\d+\.\d+\s+Development Server .* started/'; private State $state; @@ -170,7 +171,7 @@ class Server if ($stream === $pipes[2] && preg_match(self::DEV_SERVER_START_PATTERN, $line)) { continue; } - if (preg_match('/]\s+\S+:\d+\s+(Accepted|Closing)/', $line)) { + if (preg_match(self::PATTERN_SERVER_LOG_FILTER, $line)) { continue; } diff --git a/src/Appwrite/Platform/Tasks/Install.php b/src/Appwrite/Platform/Tasks/Install.php index 68fb8137f9..84ceb7fbc8 100644 --- a/src/Appwrite/Platform/Tasks/Install.php +++ b/src/Appwrite/Platform/Tasks/Install.php @@ -23,6 +23,10 @@ class Install extends Action private const int HEALTH_CHECK_ATTEMPTS = 10; private const int HEALTH_CHECK_DELAY_SECONDS = 3; + private const string PATTERN_ENV_VAR_NAME = '/^[A-Z0-9_]+$/'; + private const string PATTERN_DB_PASSWORD_VAR = '/^_APP_DB_.*_PASS$/'; + private const string PATTERN_SESSION_COOKIE = '/a_session_console=([^;]+)/'; + protected string $hostPath = ''; protected ?bool $isLocalInstall = null; protected ?array $installerConfig = null; @@ -666,7 +670,7 @@ class Install extends Action $headers = $response->getHeaders(); $setCookie = $headers['set-cookie'] ?? $headers['Set-Cookie'] ?? null; - if (!$setCookie || !preg_match('/a_session_console=([^;]+)/', $setCookie, $matches)) { + if (!$setCookie || !preg_match(self::PATTERN_SESSION_COOKIE, $setCookie, $matches)) { throw new \Exception('Session created but no cookie found'); } @@ -750,7 +754,7 @@ class Install extends Action if ($value === null || $value === '') { continue; } - if (!preg_match('/^[A-Z0-9_]+$/', $key)) { + if (!preg_match(self::PATTERN_ENV_VAR_NAME, $key)) { throw new \Exception("Invalid environment variable name: $key"); } $env .= $key . '=' . \escapeshellarg((string) $value) . ' '; @@ -877,7 +881,7 @@ class Install extends Action protected function generatePasswordValue(string $varName, Password $password): string { $value = $password->generate(); - if (!\preg_match('/^_APP_DB_.*_PASS$/', $varName)) { + if (!\preg_match(self::PATTERN_DB_PASSWORD_VAR, $varName)) { return $value; }