Skip to content

Commit 3a4ff3d

Browse files
authored
Escape OTLP endpoints JSON before YAML single-quote wrapping (#30527)
1 parent 0b2249c commit 3a4ff3d

2 files changed

Lines changed: 29 additions & 1 deletion

File tree

pkg/workflow/observability_otlp.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,8 @@ func (c *Compiler) injectOTLPConfig(workflowData *WorkflowData) {
399399
// The value is single-quoted to prevent YAML parsers from interpreting the
400400
// leading '[' as a YAML sequence node rather than a plain string.
401401
if encoded := encodeOTLPEndpoints(entries); encoded != "" {
402-
otlpEnvLines += "\n GH_AW_OTLP_ENDPOINTS: '" + encoded + "'"
402+
escapedEncoded := strings.ReplaceAll(encoded, "'", "''")
403+
otlpEnvLines += "\n GH_AW_OTLP_ENDPOINTS: '" + escapedEncoded + "'"
403404
otlpLog.Printf("Injected GH_AW_OTLP_ENDPOINTS env var")
404405
}
405406

pkg/workflow/observability_otlp_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,33 @@ func TestInjectOTLPConfig_MultipleEndpoints(t *testing.T) {
10601060
assert.Contains(t, wd.Env, "secondary.example.com", "secondary endpoint should appear in GH_AW_OTLP_ENDPOINTS")
10611061
})
10621062

1063+
t.Run("escapes single quotes in GH_AW_OTLP_ENDPOINTS", func(t *testing.T) {
1064+
wd := &WorkflowData{
1065+
RawFrontmatter: map[string]any{
1066+
"observability": map[string]any{
1067+
"otlp": map[string]any{
1068+
"endpoint": []any{
1069+
map[string]any{
1070+
"url": "https://primary.example.com:4317",
1071+
"headers": map[string]any{"Authorization": "Bearer O'Reilly"},
1072+
},
1073+
map[string]any{"url": "https://secondary.example.com:4317"},
1074+
},
1075+
},
1076+
},
1077+
},
1078+
}
1079+
c.injectOTLPConfig(wd)
1080+
1081+
assert.Contains(t, wd.Env, "GH_AW_OTLP_ENDPOINTS:", "multi-endpoint env var should be injected")
1082+
assert.Contains(
1083+
t,
1084+
wd.Env,
1085+
"GH_AW_OTLP_ENDPOINTS: '[{\"url\":\"https://primary.example.com:4317\",\"headers\":\"Authorization=Bearer O''Reilly\"}",
1086+
"single quotes must be escaped inside GH_AW_OTLP_ENDPOINTS YAML single-quoted scalar",
1087+
)
1088+
})
1089+
10631090
t.Run("adds all static endpoint domains to firewall allowlist", func(t *testing.T) {
10641091
wd := &WorkflowData{
10651092
RawFrontmatter: map[string]any{

0 commit comments

Comments
 (0)