Fix endless loop in "expandDoubleQuoted".

Fix an issue with expansion of escaped newlines.
Use the currently set mkfile vars as environment vars for the shell command invoked by "expandBackQuoted".
This commit is contained in:
DiablosOffens 2016-08-30 13:09:13 +02:00
parent 353e1eab5f
commit a3a923ffe8
3 changed files with 22 additions and 10 deletions

View file

@ -5,6 +5,7 @@ package main
import ( import (
"regexp" "regexp"
"strings" "strings"
"os"
"unicode/utf8" "unicode/utf8"
) )
@ -89,31 +90,35 @@ func expandEscape(input string) (string, int) {
if c == '\t' || c == ' ' { if c == '\t' || c == ' ' {
return string(c), w return string(c), w
} }
if c == '\n' {
return "", w
}
return "\\" + string(c), w return "\\" + string(c), w
} }
// Expand a double quoted string starting after a '\"' // Expand a double quoted string starting after a '\"'
func expandDoubleQuoted(input string, vars map[string][]string, expandBackticks bool) (string, int) { func expandDoubleQuoted(input string, vars map[string][]string, expandBackticks bool) (string, int) {
// find the first non-escaped " // find the first non-escaped "
i := 0
j := 0 j := 0
for { for {
j = strings.IndexAny(input[j:], "\"\\") j = strings.IndexAny(input[i:], "\"\\")
if j < 0 { if j < 0 {
break break
} }
j += i
c, w := utf8.DecodeRuneInString(input[j:]) c, w := utf8.DecodeRuneInString(input[j:])
j += w i = j + w
if c == '"' { if c == '"' {
return strings.Join(expand(input[:j], vars, expandBackticks), " "), (j + w) return strings.Join(expand(input[:j], vars, expandBackticks), " "), i
} }
if c == '\\' { if c == '\\' {
if j+w < len(input) { if i < len(input) {
j += w _, w := utf8.DecodeRuneInString(input[i:])
_, w := utf8.DecodeRuneInString(input[j:]) i += w
j += w
} else { } else {
break break
} }
@ -304,8 +309,13 @@ func expandBackQuoted(input string, vars map[string][]string) ([]string, int) {
return []string{input}, len(input) return []string{input}, len(input)
} }
env := os.Environ()
for key, values := range vars {
env = append(env, key + "=" + strings.Join(values, " "))
}
// TODO: handle errors // TODO: handle errors
output, _ := subprocess("sh", nil, input[:j], true) output, _ := subprocess("sh", nil, env, input[:j], true)
parts := make([]string, 0) parts := make([]string, 0)
_, tokens := lexWords(output) _, tokens := lexWords(output)

View file

@ -118,7 +118,7 @@ func parsePipeInclude(p *parser, t token) parserStateFun {
args[i] = p.tokenbuf[i].val args[i] = p.tokenbuf[i].val
} }
output, success := subprocess("sh", args, "", true) output, success := subprocess("sh", args, nil, "", true)
if !success { if !success {
p.basicErrorAtToken("subprocess include failed", t) p.basicErrorAtToken("subprocess include failed", t)
} }

View file

@ -106,6 +106,7 @@ func dorecipe(target string, u *node, e *edge, dryrun bool) bool {
_, success := subprocess( _, success := subprocess(
sh, sh,
args, args,
nil,
input, input,
false) false)
@ -127,6 +128,7 @@ func dorecipe(target string, u *node, e *edge, dryrun bool) bool {
// //
func subprocess(program string, func subprocess(program string,
args []string, args []string,
env []string,
input string, input string,
capture_out bool) (string, bool) { capture_out bool) (string, bool) {
program_path, err := exec.LookPath(program) program_path, err := exec.LookPath(program)
@ -142,7 +144,7 @@ func subprocess(program string,
log.Fatal(err) log.Fatal(err)
} }
attr := os.ProcAttr{Files: []*os.File{stdin_pipe_read, os.Stdout, os.Stderr}} attr := os.ProcAttr{Env: env, Files: []*os.File{stdin_pipe_read, os.Stdout, os.Stderr}}
output := make([]byte, 0) output := make([]byte, 0)
capture_done := make(chan bool) capture_done := make(chan bool)