Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3d5f6a10 authored by Paul Duffin's avatar Paul Duffin Committed by Gerrit Code Review
Browse files

Merge "Prevent invalid paths being added to mock file system"

parents c737facd 80f4cea1
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ package android

import (
	"fmt"
	"strings"
	"testing"
)

@@ -241,6 +242,7 @@ type MockFS map[string][]byte
// Fails if the supplied map files with the same paths are present in both of them.
func (fs MockFS) Merge(extra map[string][]byte) {
	for p, c := range extra {
		validateFixtureMockFSPath(p)
		if _, ok := fs[p]; ok {
			panic(fmt.Errorf("attempted to add file %s to the mock filesystem but it already exists", p))
		}
@@ -248,6 +250,27 @@ func (fs MockFS) Merge(extra map[string][]byte) {
	}
}

// Ensure that tests cannot add paths into the mock file system which would not be allowed in the
// runtime, e.g. absolute paths, paths relative to the 'out/' directory.
func validateFixtureMockFSPath(path string) {
	// This uses validateSafePath rather than validatePath because the latter prevents adding files
	// that include a $ but there are tests that allow files with a $ to be used, albeit only by
	// globbing.
	validatedPath, err := validateSafePath(path)
	if err != nil {
		panic(err)
	}

	// Make sure that the path is canonical.
	if validatedPath != path {
		panic(fmt.Errorf("path %q is not a canonical path, use %q instead", path, validatedPath))
	}

	if path == "out" || strings.HasPrefix(path, "out/") {
		panic(fmt.Errorf("cannot add output path %q to the mock file system", path))
	}
}

func (fs MockFS) AddToFixture() FixturePreparer {
	return FixtureMergeMockFs(fs)
}
@@ -290,6 +313,11 @@ func FixtureRegisterWithContext(registeringFunc func(ctx RegistrationContext)) F
func FixtureModifyMockFS(mutator func(fs MockFS)) FixturePreparer {
	return newSimpleFixturePreparer(func(f *fixture) {
		mutator(f.mockFS)

		// Make sure that invalid paths were not added to the mock filesystem.
		for p, _ := range f.mockFS {
			validateFixtureMockFSPath(p)
		}
	})
}

@@ -307,6 +335,7 @@ func FixtureMergeMockFs(mockFS MockFS) FixturePreparer {
// Fail if the filesystem already contains a file with that path, use FixtureOverrideFile instead.
func FixtureAddFile(path string, contents []byte) FixturePreparer {
	return FixtureModifyMockFS(func(fs MockFS) {
		validateFixtureMockFSPath(path)
		if _, ok := fs[path]; ok {
			panic(fmt.Errorf("attempted to add file %s to the mock filesystem but it already exists, use FixtureOverride*File instead", path))
		}
+38 −1
Original line number Diff line number Diff line
@@ -14,7 +14,9 @@

package android

import "testing"
import (
	"testing"
)

// Make sure that FixturePreparer instances are only called once per fixture and in the order in
// which they were added.
@@ -47,3 +49,38 @@ func TestFixtureDedup(t *testing.T) {
	AssertDeepEquals(t, "preparers called in wrong order",
		[]string{"preparer1", "preparer2", "preparer4", "preparer3"}, list)
}

func TestFixtureValidateMockFS(t *testing.T) {
	buildDir := "<unused>"
	factory := NewFixtureFactory(&buildDir)

	t.Run("absolute path", func(t *testing.T) {
		AssertPanicMessageContains(t, "source path validation failed", "Path is outside directory: /abs/path/Android.bp", func() {
			factory.Fixture(t, FixtureAddFile("/abs/path/Android.bp", nil))
		})
	})
	t.Run("not canonical", func(t *testing.T) {
		AssertPanicMessageContains(t, "source path validation failed", `path "path/with/../in/it/Android.bp" is not a canonical path, use "path/in/it/Android.bp" instead`, func() {
			factory.Fixture(t, FixtureAddFile("path/with/../in/it/Android.bp", nil))
		})
	})
	t.Run("FixtureAddFile", func(t *testing.T) {
		AssertPanicMessageContains(t, "source path validation failed", `cannot add output path "out/Android.bp" to the mock file system`, func() {
			factory.Fixture(t, FixtureAddFile("out/Android.bp", nil))
		})
	})
	t.Run("FixtureMergeMockFs", func(t *testing.T) {
		AssertPanicMessageContains(t, "source path validation failed", `cannot add output path "out/Android.bp" to the mock file system`, func() {
			factory.Fixture(t, FixtureMergeMockFs(MockFS{
				"out/Android.bp": nil,
			}))
		})
	})
	t.Run("FixtureModifyMockFS", func(t *testing.T) {
		AssertPanicMessageContains(t, "source path validation failed", `cannot add output path "out/Android.bp" to the mock file system`, func() {
			factory.Fixture(t, FixtureModifyMockFS(func(fs MockFS) {
				fs["out/Android.bp"] = nil
			}))
		})
	})
}