Merge changes Idcbe2046,I09616402,Ide2f1ed9

* changes:
  Fix sbox in chdir mode
  Check RuleBuilder temporaries for path errors
  Fix WriteFileRule escaping
diff --git a/android/defs.go b/android/defs.go
index 1a76721..1a7c459 100644
--- a/android/defs.go
+++ b/android/defs.go
@@ -145,7 +145,7 @@
 
 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 17f211b..75f1b5d 100644
--- a/android/rule_builder.go
+++ b/android/rule_builder.go
@@ -523,6 +523,12 @@
 			})
 		}
 
+		// 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.
@@ -537,7 +543,7 @@
 		}
 
 		// 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
diff --git a/cmd/sbox/sbox.go b/cmd/sbox/sbox.go
index f8919a4..f47c601 100644
--- a/cmd/sbox/sbox.go
+++ b/cmd/sbox/sbox.go
@@ -229,13 +229,18 @@
 		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 @@
 
 	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 @@
 	}
 	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
+}