mirror of
https://code.forgejo.org/actions/checkout.git
synced 2026-08-28 04:54:59 -04:00
Escape single quotes in submodule Foreach shell commands
This commit is contained in:
parent
f548e57e54
commit
3a65af85aa
5 changed files with 143 additions and 6 deletions
|
|
@ -11,6 +11,7 @@ import * as urlHelper from './url-helper.js'
|
|||
import {randomUUID} from 'crypto'
|
||||
import {IGitCommandManager} from './git-command-manager.js'
|
||||
import {IGitSourceSettings} from './git-source-settings.js'
|
||||
import {escapeSingleQuote} from './shell-escape.js'
|
||||
|
||||
const IS_WINDOWS = process.platform === 'win32'
|
||||
const SSH_COMMAND_KEY = 'core.sshCommand'
|
||||
|
|
@ -215,14 +216,14 @@ class GitAuthHelper {
|
|||
if (this.settings.sshKey) {
|
||||
// Configure core.sshCommand
|
||||
await this.git.submoduleForeach(
|
||||
`git config --local '${SSH_COMMAND_KEY}' '${this.sshCommand}'`,
|
||||
`git config --local '${SSH_COMMAND_KEY}' '${escapeSingleQuote(this.sshCommand)}'`,
|
||||
this.settings.nestedSubmodules
|
||||
)
|
||||
} else {
|
||||
// Configure HTTPS instead of SSH
|
||||
for (const insteadOfValue of this.insteadOfValues) {
|
||||
await this.git.submoduleForeach(
|
||||
`git config --local --add '${this.insteadOfKey}' '${insteadOfValue}'`,
|
||||
`git config --local --add '${escapeSingleQuote(this.insteadOfKey)}' '${escapeSingleQuote(insteadOfValue)}'`,
|
||||
this.settings.nestedSubmodules
|
||||
)
|
||||
}
|
||||
|
|
@ -536,7 +537,7 @@ class GitAuthHelper {
|
|||
const pattern = regexpHelper.escape(configKey)
|
||||
await this.git.submoduleForeach(
|
||||
// Wrap the pipeline in quotes to make sure it's handled properly by submoduleForeach, rather than just the first part of the pipeline.
|
||||
`sh -c "git config --local --name-only --get-regexp '${pattern}' && git config --local --unset-all '${configKey}' || :"`,
|
||||
`sh -c "git config --local --name-only --get-regexp '${escapeSingleQuote(pattern)}' && git config --local --unset-all '${escapeSingleQuote(configKey)}' || :"`,
|
||||
true
|
||||
)
|
||||
}
|
||||
|
|
|
|||
18
src/shell-escape.ts
Normal file
18
src/shell-escape.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/**
|
||||
* Escapes a value for safe use inside a single-quoted shell string.
|
||||
*
|
||||
* In POSIX shells, single-quoted strings treat every character literally
|
||||
* except for the single quote itself (there is no escape sequence inside
|
||||
* single quotes). The standard technique is to:
|
||||
* 1. Close the current single-quoted segment: '
|
||||
* 2. Add an escaped single quote: \'
|
||||
* 3. Re-open a new single-quoted segment: '
|
||||
*
|
||||
* Example: "it's" → "it'\''s"
|
||||
*
|
||||
* This prevents shell injection when interpolating values into commands
|
||||
* executed via `sh -c` (e.g. `git submodule foreach`).
|
||||
*/
|
||||
export function escapeSingleQuote(value: string): string {
|
||||
return value.replace(/'/g, "'\\''")
|
||||
}
|
||||
Loading…
Reference in a new issue