Skip to content

Commit

Permalink
Merge pull request #355 from OctopusDeploy/huy/2023/3/sc-82129-handle…
Browse files Browse the repository at this point in the history
…-special-character-in-variable-name

Add ability to escape special character when parse variables argument
  • Loading branch information
HuyPhanNguyen authored Jun 25, 2024
2 parents eb6ee72 + 5db396c commit 377ddb2
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
34 changes: 33 additions & 1 deletion pkg/executionscommon/executionscommon.go
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ func LookupPackageDownloadString(value bool) string {
// splitVariableString is a derivative of splitPackageOverrideString in release create.
// it is required because the builtin go strings.SplitN can't handle more than one delimeter character.
// otherwise it works the same, but caps the number of splits at 'n'

func splitVariableString(s string, n int) []string {
// pass 1: collect spans; golang strings.FieldsFunc says it's much more efficient this way
type span struct {
Expand All @@ -355,8 +356,15 @@ func splitVariableString(s string, n int) []string {

// Find the field start and end indices.
start := 0 // we always start the first span at the beginning of the string
escaped := false

for idx, ch := range s {
if ch == ':' || ch == '=' {
if ch == '\\' && !escaped {
escaped = true
continue
}

if (ch == ':' || ch == '=') && (!escaped) {
if start >= 0 { // we found a delimiter and we are already in a span; end the span and start a new one
if len(spans) == n-1 { // we're about to append the last span, break so the 'last field' code consumes the rest of the string
break
Expand All @@ -369,6 +377,8 @@ func splitVariableString(s string, n int) []string {
start = idx
}
}
} else {
escaped = false
}
}

Expand All @@ -382,9 +392,31 @@ func splitVariableString(s string, n int) []string {
for i, span := range spans {
a[i] = s[span.start:span.end]
}

// the parts
for i, part := range a {
a[i] = unescape(part)
}

return a
}

func unescape(s string) string {
result := make([]rune, 0, len(s))
escaped := false

for _, ch := range s {
if ch == '\\' && !escaped {
escaped = true
continue
}
result = append(result, ch)
escaped = false
}

return string(result)
}

// ScheduledStartTimeAnswerFormatter is passed to the DatePicker so that if the user selects a time within the next
// one minute after 'now', it will show the answer as the string "Now" rather than the actual datetime string
func ScheduledStartTimeAnswerFormatter(datePicker *surveyext.DatePicker, t time.Time) string {
Expand Down
1 change: 1 addition & 0 deletions pkg/executionscommon/executionscommon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ func TestParseVariableStringArray(t *testing.T) {
{name: "foo=bar,baz=qux", input: []string{"foo=bar", "baz=qux"}, expect: map[string]string{"foo": "bar", "baz": "qux"}},

{name: "foo:bar:more=stuff", input: []string{"foo:bar:more=stuff"}, expect: map[string]string{"foo": "bar:more=stuff"}},
{name: "foo\\:bar:more=stuff", input: []string{"foo\\:bar:more=stuff"}, expect: map[string]string{"foo:bar": "more=stuff"}},

{name: "trims whitespace", input: []string{" foo : \tbar "}, expect: map[string]string{"foo": "bar"}},

Expand Down

0 comments on commit 377ddb2

Please sign in to comment.