fix: handle escaped quotes in docker entrypoint parsing

This commit is contained in:
Aditya Tripathi
2025-11-03 21:10:32 +00:00
parent f89b86491b
commit f5d549365c
2 changed files with 49 additions and 12 deletions

View File

@@ -965,21 +965,34 @@ function convertDockerRunToCompose(?string $custom_docker_run_options = null)
} }
if ($option === '--entrypoint') { if ($option === '--entrypoint') {
// Match --entrypoint=value or --entrypoint value // Match --entrypoint=value or --entrypoint value
// Handle quoted strings: --entrypoint "sh -c 'command'" or --entrypoint='command' // Handle quoted strings with escaped quotes: --entrypoint "python -c \"print('hi')\""
// Try double quotes first, then single quotes, then unquoted // Pattern matches: double-quoted (with escapes), single-quoted (with escapes), or unquoted values
if (preg_match('/--entrypoint(?:=|\s+)"([^"]+)"/', $custom_docker_run_options, $entrypoint_matches)) { if (preg_match(
$value = $entrypoint_matches[1]; '/--entrypoint(?:=|\s+)(?<raw>"(?:\\\\.|[^"])*"|\'(?:\\\\.|[^\'])*\'|[^\s]+)/',
} elseif (preg_match("/--entrypoint(?:=|\s+)'([^']+)'/", $custom_docker_run_options, $entrypoint_matches)) { $custom_docker_run_options,
$value = $entrypoint_matches[1]; $entrypoint_matches
} elseif (preg_match('/--entrypoint(?:=|\s+)([^\s]+)/', $custom_docker_run_options, $entrypoint_matches)) { )) {
$value = $entrypoint_matches[1]; $rawValue = $entrypoint_matches['raw'];
} else { // Handle double-quoted strings: strip quotes and unescape special characters
$value = null; if (str_starts_with($rawValue, '"') && str_ends_with($rawValue, '"')) {
$inner = substr($rawValue, 1, -1);
// Unescape backslash sequences: \" \$ \` \\
$value = preg_replace('/\\\\(["$`\\\\])/', '$1', $inner);
} elseif (str_starts_with($rawValue, "'") && str_ends_with($rawValue, "'")) {
// Handle single-quoted strings: just strip quotes (no unescaping per shell rules)
$value = substr($rawValue, 1, -1);
} else {
// Handle unquoted values
$value = $rawValue;
}
} }
if ($value && ! empty(trim($value))) {
if (isset($value) && trim($value) !== '') {
$options[$option][] = $value; $options[$option][] = $value;
$options[$option] = array_unique($options[$option]); $options[$option] = array_values(array_unique($options[$option]));
} }
continue;
} }
if (isset($match[2]) && $match[2] !== '') { if (isset($match[2]) && $match[2] !== '') {
$value = $match[2]; $value = $match[2];

View File

@@ -174,3 +174,27 @@ test('ConvertEntrypointComplex', function () {
'entrypoint' => "sh -c 'npm install && npm start'", 'entrypoint' => "sh -c 'npm install && npm start'",
]); ]);
}); });
test('ConvertEntrypointWithEscapedDoubleQuotes', function () {
$input = '--entrypoint "python -c \"print(\'hi\')\""';
$output = convertDockerRunToCompose($input);
expect($output)->toBe([
'entrypoint' => "python -c \"print('hi')\"",
]);
});
test('ConvertEntrypointWithEscapedSingleQuotesInDoubleQuotes', function () {
$input = '--entrypoint "sh -c \"echo \'hello\'\""';
$output = convertDockerRunToCompose($input);
expect($output)->toBe([
'entrypoint' => "sh -c \"echo 'hello'\"",
]);
});
test('ConvertEntrypointSingleQuotedWithDoubleQuotesInside', function () {
$input = '--entrypoint \'python -c "print(\"hi\")"\'';
$output = convertDockerRunToCompose($input);
expect($output)->toBe([
'entrypoint' => 'python -c "print(\"hi\")"',
]);
});