Skip to content

Commit 60eaecd

Browse files
committed
Lint
1 parent 9f0c0d9 commit 60eaecd

File tree

3 files changed

+49
-4
lines changed

3 files changed

+49
-4
lines changed

docs/enterprise-features.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
"snow-query-for-records",
1717
"snow-wait-for-condition",
1818
"toml-parse",
19-
"toml-update"
19+
"toml-update",
20+
"kcl-run"
2021
],
2122
"pro": [
2223
"jira",

pkg/promotion/runner/builtin/kcl_run.go

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ func (k *kclRunner) writeOutput(
274274

275275
func pathLooksLikeFile(path string) bool {
276276
ext := filepath.Ext(path)
277-
return ext == ".yaml" || ext == ".yml"
277+
return ext == ".yaml" || ext == ".yml" //nolint:goconst
278278
}
279279

280280
func writeManifestDirectory(
@@ -314,7 +314,13 @@ func writeManifestDirectory(
314314
fallbackIndex++
315315
}
316316

317-
if err = os.WriteFile(filepath.Join(outPath, fileName), resource, 0o600); err != nil {
317+
outputPath, err := safeOutputResourcePath(outPath, fileName)
318+
if err != nil {
319+
return err
320+
}
321+
322+
//nolint:gosec // outputPath is constrained to outPath by basename validation and securejoin
323+
if err = os.WriteFile(outputPath, resource, 0o600); err != nil {
318324
return fmt.Errorf("failed to write resource to file %q: %w", fileName, err)
319325
}
320326
}
@@ -323,6 +329,26 @@ func writeManifestDirectory(
323329
return nil
324330
}
325331

332+
func safeOutputResourcePath(outPath string, fileName string) (string, error) {
333+
cleanName := filepath.Clean(fileName)
334+
if cleanName == "." || cleanName == ".." {
335+
return "", fmt.Errorf("invalid resource file name %q", fileName)
336+
}
337+
if filepath.IsAbs(cleanName) {
338+
return "", fmt.Errorf("resource file name %q must be relative", fileName)
339+
}
340+
if cleanName != filepath.Base(cleanName) {
341+
return "", fmt.Errorf("resource file name %q must not contain path separators", fileName)
342+
}
343+
344+
joinedPath, err := securejoin.SecureJoin(outPath, cleanName)
345+
if err != nil {
346+
return "", fmt.Errorf("failed to build output path for %q: %w", fileName, err)
347+
}
348+
349+
return joinedPath, nil
350+
}
351+
326352
func splitManifestResources(document []byte) ([][]byte, error) {
327353
var value any
328354
if err := libyaml.Unmarshal(document, &value); err != nil {

pkg/promotion/runner/builtin/kcl_run_test.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,25 @@ app = {
230230
}
231231
}
232232
`), 0o600))
233-
require.NoError(t, os.WriteFile(filepath.Join(dir, "app", "kcl.yaml"), []byte("kcl_cli_configs:\n file:\n - main.k\n\nkcl_options:\n - key: app-name\n value: demo\n - key: namespace\n value: prod\n - key: version\n value: \"v1.2.3\"\n"), 0o600))
233+
require.NoError(
234+
t,
235+
os.WriteFile(
236+
filepath.Join(dir, "app", "kcl.yaml"),
237+
[]byte(`kcl_cli_configs:
238+
file:
239+
- main.k
240+
241+
kcl_options:
242+
- key: app-name
243+
value: demo
244+
- key: namespace
245+
value: prod
246+
- key: version
247+
value: "v1.2.3"
248+
`),
249+
0o600,
250+
),
251+
)
234252
},
235253
config: configbuiltin.KCLRunConfig{
236254
Path: "./app/kcl.yaml",

0 commit comments

Comments
 (0)