Skip to content

Commit 344902a

Browse files
authored
fix: sanitize operation name (#999)
1 parent a02320d commit 344902a

File tree

3 files changed

+415
-12
lines changed

3 files changed

+415
-12
lines changed

v2/pkg/engine/datasource/graphql_datasource/graphql_datasource.go

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"strings"
1313
"sync"
1414
"time"
15+
"unicode"
1516

1617
"github.com/buger/jsonparser"
1718
"github.com/cespare/xxhash/v2"
@@ -400,19 +401,58 @@ func (p *Planner[T]) ConfigureSubscription() plan.SubscriptionConfiguration {
400401
}
401402
}
402403

404+
func sanitize(element string) string {
405+
// replace all invalid characters with underscore
406+
return strings.Map(func(r rune) rune {
407+
if !unicode.IsDigit(r) && !unicode.IsLetter(r) && r != '_' {
408+
return '_'
409+
}
410+
return r
411+
}, element)
412+
}
413+
414+
func sanitizeKey(element string) string {
415+
if element == "" {
416+
return ""
417+
}
418+
419+
sanitized := sanitize(element)
420+
421+
// remove consecutive underscores and leave only one
422+
builder := strings.Builder{}
423+
var prev rune
424+
425+
for _, r := range sanitized {
426+
if r == '_' && prev == '_' {
427+
continue
428+
}
429+
430+
builder.WriteRune(r)
431+
prev = r
432+
}
433+
434+
return builder.String()
435+
}
436+
437+
// buildUpstreamOperationName builds the name of the upstream operation.
438+
// An operation name can only contain characters, digits and underscores. All other characters are replaced with underscores.
439+
// As the subgraph name can contain special characters we need to make sure to sanitize it.
403440
func (p *Planner[T]) buildUpstreamOperationName(ref int) string {
404-
operationName := p.visitor.Operation.OperationDefinitionNameBytes(ref)
405-
if len(operationName) == 0 {
441+
operationName := p.visitor.Operation.OperationDefinitionNameBytes(ref).String()
442+
if operationName == "" {
406443
return ""
407444
}
408445

409446
fetchID := strconv.Itoa(p.dataSourcePlannerConfig.FetchID)
410447

411448
builder := strings.Builder{}
412-
builder.Grow(len(operationName) + len(p.dataSourceConfig.Name()) + len(fetchID) + 4) // 4 is for delimiters "__"
449+
operationName = strings.Trim(operationName, "_")
450+
451+
subgraphName := sanitizeKey(p.dataSourceConfig.Name())
452+
subgraphName = strings.Trim(subgraphName, "_")
413453

414-
builder.Write(operationName)
415-
builder.WriteString("__" + p.dataSourceConfig.Name() + "__" + fetchID)
454+
builder.Grow(len(operationName) + len(subgraphName) + len(fetchID) + 4) // 4 is for delimiters "__"
455+
builder.WriteString(operationName + "__" + subgraphName + "__" + fetchID)
416456

417457
return builder.String()
418458
}

0 commit comments

Comments
 (0)