fix(validation): support scoped packages in file path validation (#8928)

This commit is contained in:
Andras Bacsai
2026-03-12 13:10:48 +01:00
committed by GitHub
8 changed files with 74 additions and 16 deletions
+1 -1
View File
@@ -3929,7 +3929,7 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
private function validatePathField(string $value, string $fieldName): string
{
if (! preg_match('/^\/[a-zA-Z0-9._\-\/]+$/', $value)) {
if (! preg_match(\App\Support\ValidationPatterns::FILE_PATH_PATTERN, $value)) {
throw new \RuntimeException("Invalid {$fieldName}: contains forbidden characters.");
}
if (str_contains($value, '..')) {
+6 -6
View File
@@ -73,7 +73,7 @@ class General extends Component
#[Validate(['string', 'nullable'])]
public ?string $dockerfile = null;
#[Validate(['string', 'nullable', 'max:255', 'regex:/^\/[a-zA-Z0-9._\-\/]+$/'])]
#[Validate(['string', 'nullable', 'max:255', 'regex:/^\/[a-zA-Z0-9._\-\/~@+]+$/'])]
public ?string $dockerfileLocation = null;
#[Validate(['string', 'nullable'])]
@@ -85,7 +85,7 @@ class General extends Component
#[Validate(['string', 'nullable'])]
public ?string $dockerRegistryImageTag = null;
#[Validate(['string', 'nullable', 'max:255', 'regex:/^\/[a-zA-Z0-9._\-\/]+$/'])]
#[Validate(['string', 'nullable', 'max:255', 'regex:/^\/[a-zA-Z0-9._\-\/~@+]+$/'])]
public ?string $dockerComposeLocation = null;
#[Validate(['string', 'nullable'])]
@@ -198,8 +198,8 @@ class General extends Component
'dockerfile' => 'nullable',
'dockerRegistryImageName' => 'nullable',
'dockerRegistryImageTag' => 'nullable',
'dockerfileLocation' => ['nullable', 'regex:/^\/[a-zA-Z0-9._\-\/]+$/'],
'dockerComposeLocation' => ['nullable', 'regex:/^\/[a-zA-Z0-9._\-\/]+$/'],
'dockerfileLocation' => ['nullable', 'regex:'.ValidationPatterns::FILE_PATH_PATTERN],
'dockerComposeLocation' => ['nullable', 'regex:'.ValidationPatterns::FILE_PATH_PATTERN],
'dockerCompose' => 'nullable',
'dockerComposeRaw' => 'nullable',
'dockerfileTargetBuild' => 'nullable',
@@ -231,8 +231,8 @@ class General extends Component
return array_merge(
ValidationPatterns::combinedMessages(),
[
'dockerfileLocation.regex' => 'The Dockerfile location must be a valid path starting with / and containing only alphanumeric characters, dots, hyphens, and slashes.',
'dockerComposeLocation.regex' => 'The Docker Compose location must be a valid path starting with / and containing only alphanumeric characters, dots, hyphens, and slashes.',
...ValidationPatterns::filePathMessages('dockerfileLocation', 'Dockerfile'),
...ValidationPatterns::filePathMessages('dockerComposeLocation', 'Docker Compose'),
'name.required' => 'The Name field is required.',
'gitRepository.required' => 'The Git Repository field is required.',
'gitBranch.required' => 'The Git Branch field is required.',
@@ -168,7 +168,7 @@ class GithubPrivateRepository extends Component
'selected_repository_owner' => 'required|string|regex:/^[a-zA-Z0-9\-_]+$/',
'selected_repository_repo' => 'required|string|regex:/^[a-zA-Z0-9\-_\.]+$/',
'selected_branch_name' => ['required', 'string', new ValidGitBranch],
'docker_compose_location' => ['nullable', 'string', 'max:255', 'regex:/^\/[a-zA-Z0-9._\-\/]+$/'],
'docker_compose_location' => \App\Support\ValidationPatterns::filePathRules(),
]);
if ($validator->fails()) {
@@ -64,7 +64,7 @@ class GithubPrivateRepositoryDeployKey extends Component
'is_static' => 'required|boolean',
'publish_directory' => 'nullable|string',
'build_pack' => 'required|string',
'docker_compose_location' => ['nullable', 'string', 'max:255', 'regex:/^\/[a-zA-Z0-9._\-\/]+$/'],
'docker_compose_location' => \App\Support\ValidationPatterns::filePathRules(),
];
protected function rules()
@@ -76,7 +76,7 @@ class GithubPrivateRepositoryDeployKey extends Component
'is_static' => 'required|boolean',
'publish_directory' => 'nullable|string',
'build_pack' => 'required|string',
'docker_compose_location' => ['nullable', 'string', 'max:255', 'regex:/^\/[a-zA-Z0-9._\-\/]+$/'],
'docker_compose_location' => \App\Support\ValidationPatterns::filePathRules(),
];
}
@@ -70,7 +70,7 @@ class PublicGitRepository extends Component
'publish_directory' => 'nullable|string',
'build_pack' => 'required|string',
'base_directory' => 'nullable|string',
'docker_compose_location' => ['nullable', 'string', 'max:255', 'regex:/^\/[a-zA-Z0-9._\-\/]+$/'],
'docker_compose_location' => \App\Support\ValidationPatterns::filePathRules(),
];
protected function rules()
@@ -82,7 +82,7 @@ class PublicGitRepository extends Component
'publish_directory' => 'nullable|string',
'build_pack' => 'required|string',
'base_directory' => 'nullable|string',
'docker_compose_location' => ['nullable', 'string', 'max:255', 'regex:/^\/[a-zA-Z0-9._\-\/]+$/'],
'docker_compose_location' => \App\Support\ValidationPatterns::filePathRules(),
'git_branch' => ['required', 'string', new ValidGitBranch],
];
}
+25 -1
View File
@@ -17,6 +17,12 @@ class ValidationPatterns
*/
public const DESCRIPTION_PATTERN = '/^[\p{L}\p{M}\p{N}\s\-_.,!?()\'\"+=*@\/&]+$/u';
/**
* Pattern for file paths (dockerfile location, docker compose location, etc.)
* Allows alphanumeric, dots, hyphens, underscores, slashes, @, ~, and +
*/
public const FILE_PATH_PATTERN = '/^\/[a-zA-Z0-9._\-\/~@+]+$/';
/**
* Get validation rules for name fields
*/
@@ -81,7 +87,25 @@ class ValidationPatterns
];
}
/**
/**
* Get validation rules for file path fields (dockerfile location, docker compose location)
*/
public static function filePathRules(int $maxLength = 255): array
{
return ['nullable', 'string', 'max:'.$maxLength, 'regex:'.self::FILE_PATH_PATTERN];
}
/**
* Get validation messages for file path fields
*/
public static function filePathMessages(string $field = 'dockerfileLocation', string $label = 'Dockerfile'): array
{
return [
"{$field}.regex" => "The {$label} location must be a valid path starting with / and containing only alphanumeric characters, dots, hyphens, underscores, slashes, @, ~, and +.",
];
}
/**
* Get combined validation messages for both name and description fields
*/
public static function combinedMessages(): array