Skip to content

Commit

Permalink
Escape << in <<include(file)>> directives (#444)
Browse files Browse the repository at this point in the history
  • Loading branch information
Gabriel Simmer authored Jul 30, 2020
1 parent 8db507d commit e08af42
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 19 deletions.
23 changes: 5 additions & 18 deletions cmd/orb.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,16 @@ import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"regexp"
"sort"
"strconv"
"strings"

"github.com/CircleCI-Public/circleci-cli/api"
"github.com/CircleCI-Public/circleci-cli/client"
"github.com/CircleCI-Public/circleci-cli/filetree"
"github.com/CircleCI-Public/circleci-cli/process"
"github.com/CircleCI-Public/circleci-cli/prompt"
"github.com/CircleCI-Public/circleci-cli/references"
"github.com/CircleCI-Public/circleci-cli/settings"
Expand Down Expand Up @@ -833,27 +832,15 @@ func packOrb(opts orbOptions) error {

// Travel down a YAML node, replacing values as we go.
func inlineIncludes(node *yaml.Node, orbRoot string) error {
// View: https://regexr.com/582gb
includeRegex, err := regexp.Compile(`(?U)^<<\s*include\((.*\/*[^\/]+)\)\s*?>>$`)
if err != nil {
return err
}

// If we're dealing with a ScalarNode, we can replace the contents.
// Otherwise, we recurse into the children of the Node in search of
// a matching regex.
if node.Kind == yaml.ScalarNode && node.Value != "" {
includeMatches := includeRegex.FindStringSubmatch(node.Value)
if len(includeMatches) > 0 {
filepath := filepath.Join(orbRoot, includeMatches[1])
file, err := ioutil.ReadFile(filepath)
if err != nil {
return errors.New(fmt.Sprintf("Could not open %s for inclusion in Orb", filepath))
}

node.Value = string(file)
v, err := process.MaybeIncludeFile(node.Value, orbRoot)
if err != nil {
return err
}

node.Value = v
} else {
// I am *slightly* worried about performance related to this approach, but don't have any
// larger Orbs to test against.
Expand Down
2 changes: 1 addition & 1 deletion integration_tests/features/orb_pack.feature
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,6 @@ Feature: Orb pack
When I run `circleci orb pack src`
Then the output should contain:
"""
Error: An unexpected error occurred: Could not open src/script.sh for inclusion in Orb
Error: An unexpected error occurred: could not open src/script.sh for inclusion
"""
And the exit status should be 255
34 changes: 34 additions & 0 deletions process/process.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package process

import (
"fmt"
"io/ioutil"
"path/filepath"
"regexp"
"strings"
)

// MaybeIncludeFile replaces intsances of <<include(file)>> with the contents
// of "file", escaping instances of "<<" within the file before returning, when
// the <<include()>> parameter is the string passed.
func MaybeIncludeFile(s string, orbDirectory string) (string, error) {
// View: https://regexr.com/582gb
includeRegex, err := regexp.Compile(`(?U)^<<\s*include\((.*\/*[^\/]+)\)\s*?>>$`)
if err != nil {
return s, err
}

includeMatches := includeRegex.FindStringSubmatch(s)
if len(includeMatches) > 0 {
filepath := filepath.Join(orbDirectory, includeMatches[1])
file, err := ioutil.ReadFile(filepath)
if err != nil {
return "", fmt.Errorf("could not open %s for inclusion", filepath)
}
escaped := strings.ReplaceAll(string(file), "<<", "\\<<")

return escaped, nil
}

return s, nil
}

1 comment on commit e08af42

@roopakv
Copy link

@roopakv roopakv commented on e08af42 Aug 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this broke me :(

I was moving my scripts to files and going to do the env vars later, but this now escapes actual params.

Please sign in to comment.