From 1c217fdc96dd20322e58b9b8f26f8458df337053 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 12 Mar 2021 17:24:18 -0800 Subject: [PATCH 1/3] Fix WriteFileRule escaping WriteFileRule shouldn't force the caller to ninja escape the input, and should shell escape spaces. Bug: 182612695 Test: manual Change-Id: Ide2f1ed92783eef7883279238de209d992d8f735 --- android/defs.go | 2 +- android/rule_builder.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/android/defs.go b/android/defs.go index 1a767214c..1a7c459ec 100644 --- a/android/defs.go +++ b/android/defs.go @@ -145,7 +145,7 @@ var ( func buildWriteFileRule(ctx BuilderContext, outputFile WritablePath, content string) { content = echoEscaper.Replace(content) - content = proptools.ShellEscape(content) + content = proptools.NinjaEscape(proptools.ShellEscapeIncludingSpaces(content)) if content == "" { content = "''" } diff --git a/android/rule_builder.go b/android/rule_builder.go index 17f211bf3..41d2fa64b 100644 --- a/android/rule_builder.go +++ b/android/rule_builder.go @@ -537,7 +537,7 @@ func (r *RuleBuilder) Build(name string, desc string) { } // Create a rule to write the manifest as a the textproto. - WriteFileRule(r.ctx, r.sboxManifestPath, proptools.NinjaEscape(proto.MarshalTextString(&manifest))) + WriteFileRule(r.ctx, r.sboxManifestPath, proto.MarshalTextString(&manifest)) // Generate a new string to use as the command line of the sbox rule. This uses // a RuleBuilderCommand as a convenience method of building the command line, then From 5334edd2f34bf699c56c8145975da3294f5fcf11 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 11 Mar 2021 17:18:21 -0800 Subject: [PATCH 2/3] Check RuleBuilder temporaries for path errors Output files in sandboxed RuleBuilder rules must be under the output directory, but output paths that were marked as temporaries were not error checked. Bug: 182612695 Test: rule_builder_test.go Change-Id: I09616402ef1637c2c455ec7d345a296711582e8f --- android/rule_builder.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/android/rule_builder.go b/android/rule_builder.go index 41d2fa64b..75f1b5d9c 100644 --- a/android/rule_builder.go +++ b/android/rule_builder.go @@ -523,6 +523,12 @@ func (r *RuleBuilder) Build(name string, desc string) { }) } + // Outputs that were marked Temporary will not be checked that they are in the output + // directory by the loop above, check them here. + for path := range r.temporariesSet { + Rel(r.ctx, r.outDir.String(), path.String()) + } + // Add a hash of the list of input files to the manifest so that the textproto file // changes when the list of input files changes and causes the sbox rule that // depends on it to rerun. From c590ec4bdaeb55d6db58d3e6e611c0b58f1bb31f Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 11 Mar 2021 17:20:02 -0800 Subject: [PATCH 3/3] Fix sbox in chdir mode When running commands in chdir mode sbox needs to translate the directory placeholders to paths relative to the sandbox directory instead of relative to the top of the source tree. Also translate relative PATH entries into absolute paths so they are still valid when the current directory is changed. Bug: 182612695 Test: manual Change-Id: Idcbe20466888909d423d62788bc9c35f4e03b398 --- cmd/sbox/sbox.go | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/cmd/sbox/sbox.go b/cmd/sbox/sbox.go index f8919a400..f47c6012e 100644 --- a/cmd/sbox/sbox.go +++ b/cmd/sbox/sbox.go @@ -229,13 +229,18 @@ func runCommand(command *sbox_proto.Command, tempDir string) (depFile string, er return "", err } + pathToTempDirInSbox := tempDir + if command.GetChdir() { + pathToTempDirInSbox = "." + } + if strings.Contains(rawCommand, depFilePlaceholder) { - depFile = filepath.Join(tempDir, "deps.d") + depFile = filepath.Join(pathToTempDirInSbox, "deps.d") rawCommand = strings.Replace(rawCommand, depFilePlaceholder, depFile, -1) } if strings.Contains(rawCommand, sandboxDirPlaceholder) { - rawCommand = strings.Replace(rawCommand, sandboxDirPlaceholder, tempDir, -1) + rawCommand = strings.Replace(rawCommand, sandboxDirPlaceholder, pathToTempDirInSbox, -1) } // Emulate ninja's behavior of creating the directories for any output files before @@ -254,6 +259,15 @@ func runCommand(command *sbox_proto.Command, tempDir string) (depFile string, er if command.GetChdir() { cmd.Dir = tempDir + path := os.Getenv("PATH") + absPath, err := makeAbsPathEnv(path) + if err != nil { + return "", err + } + err = os.Setenv("PATH", absPath) + if err != nil { + return "", fmt.Errorf("Failed to update PATH: %w", err) + } } err = cmd.Run() @@ -466,3 +480,17 @@ func joinPath(dir, file string) string { } return filepath.Join(dir, file) } + +func makeAbsPathEnv(pathEnv string) (string, error) { + pathEnvElements := filepath.SplitList(pathEnv) + for i, p := range pathEnvElements { + if !filepath.IsAbs(p) { + absPath, err := filepath.Abs(p) + if err != nil { + return "", fmt.Errorf("failed to make PATH entry %q absolute: %w", p, err) + } + pathEnvElements[i] = absPath + } + } + return strings.Join(pathEnvElements, string(filepath.ListSeparator)), nil +}