diff --git a/java/app_builder.go b/java/app_builder.go index 954ca4464..e27b1b70e 100644 --- a/java/app_builder.go +++ b/java/app_builder.go @@ -103,10 +103,10 @@ var buildAAR = pctx.AndroidStaticRule("buildAAR", `cp ${manifest} ${outDir}/AndroidManifest.xml && ` + `cp ${classesJar} ${outDir}/classes.jar && ` + `cp ${rTxt} ${outDir}/R.txt && ` + - `${config.SoongZipCmd} -jar -o $out -C ${outDir} -D ${outDir} ${resArgs}`, + `${config.SoongZipCmd} -jar -o $out -C ${outDir} -D ${outDir}`, CommandDeps: []string{"${config.SoongZipCmd}"}, }, - "manifest", "classesJar", "rTxt", "resArgs", "outDir") + "manifest", "classesJar", "rTxt", "outDir") func BuildAAR(ctx android.ModuleContext, outputFile android.WritablePath, classesJar, manifest, rTxt android.Path, res android.Paths) { diff --git a/java/builder.go b/java/builder.go index 48b5a7b6c..07af8ebda 100644 --- a/java/builder.go +++ b/java/builder.go @@ -321,7 +321,7 @@ func TransformResourcesToJar(ctx android.ModuleContext, outputFile android.Writa Output: outputFile, Implicits: deps, Args: map[string]string{ - "jarArgs": strings.Join(proptools.NinjaEscape(jarArgs), " "), + "jarArgs": strings.Join(proptools.NinjaAndShellEscape(jarArgs), " "), }, }) } diff --git a/java/java_resources.go b/java/java_resources.go index fdc159063..6c1fd39d0 100644 --- a/java/java_resources.go +++ b/java/java_resources.go @@ -19,6 +19,8 @@ import ( "path/filepath" "strings" + "github.com/google/blueprint/pathtools" + "android/soong/android" ) @@ -64,7 +66,7 @@ func ResourceDirsToJarArgs(ctx android.ModuleContext, if !strings.HasPrefix(path, dir.String()) { panic(fmt.Errorf("path %q does not start with %q", path, dir)) } - args = append(args, "-f", path) + args = append(args, "-f", pathtools.MatchEscape(path)) } } } @@ -107,7 +109,7 @@ func resourceFilesToJarArgs(ctx android.ModuleContext, if i == 0 || dir != lastDir { args = append(args, "-C", dir) } - args = append(args, "-f", path) + args = append(args, "-f", pathtools.MatchEscape(path)) lastDir = dir } diff --git a/zip/zip.go b/zip/zip.go index e7de6f8cc..7eebf06ed 100644 --- a/zip/zip.go +++ b/zip/zip.go @@ -27,6 +27,7 @@ import ( "sort" "strings" "sync" + "syscall" "time" "unicode" @@ -163,6 +164,15 @@ func (b *FileArgsBuilder) FileArgs() []FileArg { return b.fileArgs } +type IncorrectRelativeRootError struct { + RelativeRoot string + Path string +} + +func (x IncorrectRelativeRootError) Error() string { + return fmt.Sprintf("path %q is outside relative root %q", x.Path, x.RelativeRoot) +} + type ZipWriter struct { time time.Time createdFiles map[string]string @@ -271,9 +281,47 @@ func ZipTo(args ZipArgs, w io.Writer) error { noCompression := args.CompressionLevel == 0 for _, fa := range args.FileArgs { - srcs := fa.SourceFiles + var srcs []string + for _, s := range fa.SourceFiles { + s = strings.TrimSpace(s) + if s == "" { + continue + } + + globbed, _, err := z.fs.Glob(s, nil, pathtools.DontFollowSymlinks) + if err != nil { + return err + } + if len(globbed) == 0 { + return &os.PathError{ + Op: "stat", + Path: s, + Err: os.ErrNotExist, + } + } + srcs = append(srcs, globbed...) + } if fa.GlobDir != "" { - srcs = append(srcs, recursiveGlobFiles(fa.GlobDir)...) + if exists, isDir, err := z.fs.Exists(fa.GlobDir); err != nil { + return err + } else if !exists { + return &os.PathError{ + Op: "stat", + Path: fa.GlobDir, + Err: os.ErrNotExist, + } + } else if !isDir { + return &os.PathError{ + Op: "stat", + Path: fa.GlobDir, + Err: syscall.ENOTDIR, + } + } + globbed, _, err := z.fs.Glob(filepath.Join(fa.GlobDir, "**/*"), nil, pathtools.DontFollowSymlinks) + if err != nil { + return err + } + srcs = append(srcs, globbed...) } for _, src := range srcs { err := fillPathPairs(fa, src, &pathMappings, args.NonDeflatedFiles, noCompression) @@ -328,11 +376,6 @@ func Zip(args ZipArgs) error { func fillPathPairs(fa FileArg, src string, pathMappings *[]pathMapping, nonDeflatedFiles map[string]bool, noCompression bool) error { - src = strings.TrimSpace(src) - if src == "" { - return nil - } - src = filepath.Clean(src) var dest string if fa.JunkPaths { @@ -343,6 +386,13 @@ func fillPathPairs(fa FileArg, src string, pathMappings *[]pathMapping, if err != nil { return err } + if strings.HasPrefix(dest, "../") { + return IncorrectRelativeRootError{ + Path: src, + RelativeRoot: fa.SourcePrefixToStrip, + } + } + } dest = filepath.Join(fa.PathPrefixInZip, dest) @@ -889,15 +939,3 @@ func (z *ZipWriter) writeSymlink(rel, file string) error { return nil } - -func recursiveGlobFiles(path string) []string { - var files []string - filepath.Walk(path, func(path string, info os.FileInfo, err error) error { - if !info.IsDir() { - files = append(files, path) - } - return nil - }) - - return files -} diff --git a/zip/zip_test.go b/zip/zip_test.go index 0c2105c67..e77801b91 100644 --- a/zip/zip_test.go +++ b/zip/zip_test.go @@ -129,6 +129,34 @@ func TestZip(t *testing.T) { fh("c", fileC, zip.Deflate), }, }, + { + name: "files glob", + args: fileArgsBuilder(). + SourcePrefixToStrip("a"). + File("a/**/*"), + compressionLevel: 9, + + files: []zip.FileHeader{ + fh("a/a", fileA, zip.Deflate), + fh("a/b", fileB, zip.Deflate), + fhLink("a/c", "../../c"), + fhLink("a/d", "b"), + }, + }, + { + name: "dir", + args: fileArgsBuilder(). + SourcePrefixToStrip("a"). + Dir("a"), + compressionLevel: 9, + + files: []zip.FileHeader{ + fh("a/a", fileA, zip.Deflate), + fh("a/b", fileB, zip.Deflate), + fhLink("a/c", "../../c"), + fhLink("a/d", "b"), + }, + }, { name: "stored files", args: fileArgsBuilder(). @@ -297,12 +325,25 @@ func TestZip(t *testing.T) { File("missing"), err: os.ErrNotExist, }, + { + name: "error missing dir", + args: fileArgsBuilder(). + Dir("missing"), + err: os.ErrNotExist, + }, { name: "error missing file in list", args: fileArgsBuilder(). List("l2"), err: os.ErrNotExist, }, + { + name: "error incorrect relative root", + args: fileArgsBuilder(). + SourcePrefixToStrip("b"). + File("a/a/a"), + err: IncorrectRelativeRootError{}, + }, } for _, test := range testCases { @@ -330,6 +371,10 @@ func TestZip(t *testing.T) { if !os.IsNotExist(test.err) { t.Fatalf("want error %v, got %v", test.err, err) } + } else if _, wantRelativeRootErr := test.err.(IncorrectRelativeRootError); wantRelativeRootErr { + if _, gotRelativeRootErr := err.(IncorrectRelativeRootError); !gotRelativeRootErr { + t.Fatalf("want error %v, got %v", test.err, err) + } } else { t.Fatalf("want error %v, got %v", test.err, err) }