?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{|}~'; } /** * Ensure that parameters (database names, usernames, etc.) * only contain allowed characters before used in SQL statements * (or file names in the case of SQLiteDatabaseManager). * * By default, only the characters in static::allowedParameterCharacters() are allowed. * * Null parameters are skipped. * * @throws InvalidArgumentException */ protected static function validateParameter(string|array|null $parameters, string|null $allowedCharacters = null): void { $allowedCharacters ??= static::allowedParameterCharacters(); foreach ((array) $parameters as $parameter) { if (is_null($parameter)) { // Skip if there's nothing to validate // (e.g. when $tenant->database()->getUsername() of an // improperly created tenant is null and it gets passed). continue; } if (! is_string($parameter)) { throw new InvalidArgumentException('Parameter has to be a string.'); } 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 (static::allowedPasswordCharacters()) * before 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 static function validatePassword(string|null $password): void { static::validateParameter($password, allowedCharacters: static::allowedPasswordCharacters()); } }