?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{|}~'; /** * Ensure that parameter (database name, username, etc.) * only contains allowed characters before being used in SQL statements * (or paths in the case of SQLiteDatabaseManager). * * By default, only the characters in $allowedParameterCharacters are allowed. * * @throws InvalidArgumentException */ protected function validateParameter(mixed $parameter, string|null $allowedCharacters = null): void { if (is_null($parameter)) { throw new InvalidArgumentException('Parameter cannot be null.'); } if (is_numeric($parameter)) { $parameter = (string) $parameter; } if (! is_string($parameter)) { throw new InvalidArgumentException('Parameter has to be a string.'); } if ($parameter === '') { throw new InvalidArgumentException('Parameter cannot be an empty string.'); } $allowedCharacters ??= static::$allowedParameterCharacters; foreach (str_split($parameter) as $character) { if (! str_contains($allowedCharacters, $character)) { throw new InvalidArgumentException("Forbidden character '{$character}' in parameter."); } } } /** * Ensure password only contains allowed characters ($allowedPasswordCharacters) * before being used in SQL statements. * * Used in permission controlled managers as a shorthand for calling validateParameter() * with the less strict allowlist to validate database user passwords. * * @throws InvalidArgumentException */ protected function validatePassword(string|null $password): void { if (is_null($password)) { throw new InvalidArgumentException('Password cannot be null.'); } if ($password === '') { throw new InvalidArgumentException('Password cannot be an empty string.'); } $this->validateParameter($password, allowedCharacters: static::$allowedPasswordCharacters); } }