Allow '$' in some paths

The icu resource directories contain filenames that have '$'
characters.

Allow paths returned by the Glob functions to contain '$', on the
assumption that real paths on disk are unlikely to contain strings
that are valid ninja variables.  Fix the Build rules to escape any
paths that are passed as Path arguments.  Fix the resource rules to
manually escape the paths that are passed as strings.

Test: m checkbuild
Change-Id: Ie631bc6d96259e592adb280491a365c0df7ed0e2
This commit is contained in:
Colin Cross
2018-09-12 10:02:13 -07:00
parent c747535cc2
commit fe4bc36f87
4 changed files with 35 additions and 17 deletions

View File

@@ -23,6 +23,7 @@ import (
"github.com/google/blueprint" "github.com/google/blueprint"
"github.com/google/blueprint/pathtools" "github.com/google/blueprint/pathtools"
"github.com/google/blueprint/proptools"
) )
var ( var (
@@ -844,6 +845,13 @@ func convertBuildParams(params BuildParams) blueprint.BuildParams {
bparams.Implicits = append(bparams.Implicits, params.Implicit.String()) bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
} }
bparams.Outputs = proptools.NinjaEscape(bparams.Outputs)
bparams.ImplicitOutputs = proptools.NinjaEscape(bparams.ImplicitOutputs)
bparams.Inputs = proptools.NinjaEscape(bparams.Inputs)
bparams.Implicits = proptools.NinjaEscape(bparams.Implicits)
bparams.OrderOnly = proptools.NinjaEscape(bparams.OrderOnly)
bparams.Depfile = proptools.NinjaEscape([]string{bparams.Depfile})[0]
return bparams return bparams
} }

View File

@@ -124,7 +124,11 @@ func (p PackageContext) RuleFunc(name string,
// package-scoped variable's initialization. // package-scoped variable's initialization.
func (p PackageContext) SourcePathVariable(name, path string) blueprint.Variable { func (p PackageContext) SourcePathVariable(name, path string) blueprint.Variable {
return p.VariableFunc(name, func(ctx PackageVarContext) string { return p.VariableFunc(name, func(ctx PackageVarContext) string {
return safePathForSource(ctx, path).String() p, err := safePathForSource(ctx, path)
if err != nil {
ctx.Errorf("%s", err.Error())
}
return p.String()
}) })
} }
@@ -136,7 +140,10 @@ func (p PackageContext) SourcePathsVariable(name, separator string, paths ...str
return p.VariableFunc(name, func(ctx PackageVarContext) string { return p.VariableFunc(name, func(ctx PackageVarContext) string {
var ret []string var ret []string
for _, path := range paths { for _, path := range paths {
p := safePathForSource(ctx, path) p, err := safePathForSource(ctx, path)
if err != nil {
ctx.Errorf("%s", err.Error())
}
ret = append(ret, p.String()) ret = append(ret, p.String())
} }
return strings.Join(ret, separator) return strings.Join(ret, separator)
@@ -150,7 +157,10 @@ func (p PackageContext) SourcePathsVariable(name, separator string, paths ...str
// as part of a package-scoped variable's initialization. // as part of a package-scoped variable's initialization.
func (p PackageContext) SourcePathVariableWithEnvOverride(name, path, env string) blueprint.Variable { func (p PackageContext) SourcePathVariableWithEnvOverride(name, path, env string) blueprint.Variable {
return p.VariableFunc(name, func(ctx PackageVarContext) string { return p.VariableFunc(name, func(ctx PackageVarContext) string {
p := safePathForSource(ctx, path) p, err := safePathForSource(ctx, path)
if err != nil {
ctx.Errorf("%s", err.Error())
}
return ctx.Config().GetenvWithDefault(env, p.String()) return ctx.Config().GetenvWithDefault(env, p.String())
}) })
} }

View File

@@ -230,6 +230,8 @@ func PathsForModuleSrc(ctx ModuleContext, paths []string) Paths {
// pathsForModuleSrcFromFullPath returns Paths rooted from the module's local // pathsForModuleSrcFromFullPath returns Paths rooted from the module's local
// source directory, but strip the local source directory from the beginning of // source directory, but strip the local source directory from the beginning of
// each string. If incDirs is false, strip paths with a trailing '/' from the list. // each string. If incDirs is false, strip paths with a trailing '/' from the list.
// It intended for use in globs that only list files that exist, so it allows '$' in
// filenames.
func pathsForModuleSrcFromFullPath(ctx ModuleContext, paths []string, incDirs bool) Paths { func pathsForModuleSrcFromFullPath(ctx ModuleContext, paths []string, incDirs bool) Paths {
prefix := filepath.Join(ctx.Config().srcDir, ctx.ModuleDir()) + "/" prefix := filepath.Join(ctx.Config().srcDir, ctx.ModuleDir()) + "/"
if prefix == "./" { if prefix == "./" {
@@ -246,7 +248,7 @@ func pathsForModuleSrcFromFullPath(ctx ModuleContext, paths []string, incDirs bo
continue continue
} }
srcPath, err := pathForSource(ctx, ctx.ModuleDir(), path[len(prefix):]) srcPath, err := safePathForSource(ctx, ctx.ModuleDir(), path[len(prefix):])
if err != nil { if err != nil {
reportPathError(ctx, err) reportPathError(ctx, err)
continue continue
@@ -494,29 +496,26 @@ func (p SourcePath) withRel(rel string) SourcePath {
// safePathForSource is for paths that we expect are safe -- only for use by go // safePathForSource is for paths that we expect are safe -- only for use by go
// code that is embedding ninja variables in paths // code that is embedding ninja variables in paths
func safePathForSource(ctx PathContext, path string) SourcePath { func safePathForSource(ctx PathContext, pathComponents ...string) (SourcePath, error) {
p, err := validateSafePath(path) p, err := validateSafePath(pathComponents...)
if err != nil {
reportPathError(ctx, err)
}
ret := SourcePath{basePath{p, ctx.Config(), ""}} ret := SourcePath{basePath{p, ctx.Config(), ""}}
if err != nil {
return ret, err
}
abs, err := filepath.Abs(ret.String()) abs, err := filepath.Abs(ret.String())
if err != nil { if err != nil {
reportPathError(ctx, err) return ret, err
return ret
} }
buildroot, err := filepath.Abs(ctx.Config().buildDir) buildroot, err := filepath.Abs(ctx.Config().buildDir)
if err != nil { if err != nil {
reportPathError(ctx, err) return ret, err
return ret
} }
if strings.HasPrefix(abs, buildroot) { if strings.HasPrefix(abs, buildroot) {
reportPathErrorf(ctx, "source path %s is in output", abs) return ret, fmt.Errorf("source path %s is in output", abs)
return ret
} }
return ret return ret, err
} }
// pathForSource creates a SourcePath from pathComponents, but does not check that it exists. // pathForSource creates a SourcePath from pathComponents, but does not check that it exists.

View File

@@ -24,6 +24,7 @@ import (
"strings" "strings"
"github.com/google/blueprint" "github.com/google/blueprint"
"github.com/google/blueprint/proptools"
"android/soong/android" "android/soong/android"
) )
@@ -320,7 +321,7 @@ func TransformResourcesToJar(ctx android.ModuleContext, outputFile android.Writa
Output: outputFile, Output: outputFile,
Implicits: deps, Implicits: deps,
Args: map[string]string{ Args: map[string]string{
"jarArgs": strings.Join(jarArgs, " "), "jarArgs": strings.Join(proptools.NinjaEscape(jarArgs), " "),
}, },
}) })
} }