github.com/ssube/gitlab-ci-multi-runner@v1.2.1-0.20160607142738-b8d1285632e6/helpers/shell_escape.go (about)

     1  package helpers
     2  
     3  // https://github.com/zimbatm/direnv/blob/master/shell.go
     4  
     5  import (
     6  	"fmt"
     7  	"strings"
     8  )
     9  
    10  /*
    11   * Escaping
    12   */
    13  
    14  const (
    15  	ACK           = 6
    16  	TAB           = 9
    17  	LF            = 10
    18  	CR            = 13
    19  	US            = 31
    20  	SPACE         = 32
    21  	AMPERSTAND    = 38
    22  	SINGLE_QUOTE  = 39
    23  	PLUS          = 43
    24  	NINE          = 57
    25  	QUESTION      = 63
    26  	LOWERCASE_Z   = 90
    27  	OPEN_BRACKET  = 91
    28  	BACKSLASH     = 92
    29  	UNDERSCORE    = 95
    30  	CLOSE_BRACKET = 93
    31  	BACKTICK      = 96
    32  	TILDA         = 126
    33  	DEL           = 127
    34  )
    35  
    36  // ShellEscape is taken from https://github.com/solidsnack/shell-escape/blob/master/Text/ShellEscape/Bash.hs
    37  /*
    38  A Bash escaped string. The strings are wrapped in @$\'...\'@ if any
    39  bytes within them must be escaped; otherwise, they are left as is.
    40  Newlines and other control characters are represented as ANSI escape
    41  sequences. High bytes are represented as hex codes. Thus Bash escaped
    42  strings will always fit on one line and never contain non-ASCII bytes.
    43  */
    44  func ShellEscape(str string) string {
    45  	if str == "" {
    46  		return "''"
    47  	}
    48  	in := []byte(str)
    49  	out := ""
    50  	i := 0
    51  	l := len(in)
    52  	escape := false
    53  
    54  	hex := func(char byte) {
    55  		escape = true
    56  		out += fmt.Sprintf("\\x%02x", char)
    57  	}
    58  
    59  	backslash := func(char byte) {
    60  		escape = true
    61  		out += string([]byte{BACKSLASH, char})
    62  	}
    63  
    64  	escaped := func(str string) {
    65  		escape = true
    66  		out += str
    67  	}
    68  
    69  	quoted := func(char byte) {
    70  		escape = true
    71  		out += string([]byte{char})
    72  	}
    73  
    74  	literal := func(char byte) {
    75  		out += string([]byte{char})
    76  	}
    77  
    78  	for i < l {
    79  		char := in[i]
    80  		switch {
    81  		case char == TAB:
    82  			escaped(`\t`)
    83  		case char == LF:
    84  			escaped(`\n`)
    85  		case char == CR:
    86  			escaped(`\r`)
    87  		case char <= US:
    88  			hex(char)
    89  		case char <= AMPERSTAND:
    90  			quoted(char)
    91  		case char == SINGLE_QUOTE:
    92  			backslash(char)
    93  		case char <= PLUS:
    94  			quoted(char)
    95  		case char <= NINE:
    96  			literal(char)
    97  		case char <= QUESTION:
    98  			quoted(char)
    99  		case char <= LOWERCASE_Z:
   100  			literal(char)
   101  		case char == OPEN_BRACKET:
   102  			quoted(char)
   103  		case char == BACKSLASH:
   104  			backslash(char)
   105  		case char <= CLOSE_BRACKET:
   106  			quoted(char)
   107  		case char == UNDERSCORE:
   108  			literal(char)
   109  		case char <= BACKTICK:
   110  			quoted(char)
   111  		case char <= LOWERCASE_Z:
   112  			literal(char)
   113  		case char <= TILDA:
   114  			quoted(char)
   115  		case char == DEL:
   116  			hex(char)
   117  		default:
   118  			hex(char)
   119  		}
   120  		i++
   121  	}
   122  
   123  	if escape {
   124  		out = "$'" + out + "'"
   125  	}
   126  
   127  	return out
   128  }
   129  
   130  func ToBackslash(path string) string {
   131  	return strings.Replace(path, "/", "\\", -1)
   132  }
   133  
   134  func ToSlash(path string) string {
   135  	return strings.Replace(path, "\\", "/", -1)
   136  }