diff --git a/android/paths.go b/android/paths.go index 20039d4a5..13b31c789 100644 --- a/android/paths.go +++ b/android/paths.go @@ -1054,6 +1054,10 @@ func Rel(ctx PathContext, basePath string, targetPath string) string { // MaybeRel performs the same function as filepath.Rel, but reports errors to a PathContext, and returns false if // targetPath is not inside basePath. func MaybeRel(ctx PathContext, basePath string, targetPath string) (string, bool) { + // filepath.Rel returns an error if one path is absolute and the other is not, handle that case first. + if filepath.IsAbs(basePath) != filepath.IsAbs(targetPath) { + return "", false + } rel, err := filepath.Rel(basePath, targetPath) if err != nil { reportPathError(ctx, err) diff --git a/android/paths_test.go b/android/paths_test.go index fbeccb1c1..c4332d26b 100644 --- a/android/paths_test.go +++ b/android/paths_test.go @@ -573,3 +573,60 @@ func TestDirectorySortedPaths(t *testing.T) { t.Errorf("FilesInDirectory(b):\n %#v\n != \n %#v", inA.Strings(), expectedA) } } + +func TestMaybeRel(t *testing.T) { + testCases := []struct { + name string + base string + target string + out string + isRel bool + }{ + { + name: "normal", + base: "a/b/c", + target: "a/b/c/d", + out: "d", + isRel: true, + }, + { + name: "parent", + base: "a/b/c/d", + target: "a/b/c", + isRel: false, + }, + { + name: "not relative", + base: "a/b", + target: "c/d", + isRel: false, + }, + { + name: "abs1", + base: "/a", + target: "a", + isRel: false, + }, + { + name: "abs2", + base: "a", + target: "/a", + isRel: false, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + ctx := &configErrorWrapper{} + out, isRel := MaybeRel(ctx, testCase.base, testCase.target) + if len(ctx.errors) > 0 { + t.Errorf("MaybeRel(..., %s, %s) reported unexpected errors %v", + testCase.base, testCase.target, ctx.errors) + } + if isRel != testCase.isRel || out != testCase.out { + t.Errorf("MaybeRel(..., %s, %s) want %v, %v got %v, %v", + testCase.base, testCase.target, testCase.out, testCase.isRel, out, isRel) + } + }) + } +}