SmartJoin incorrectly treats relative paths containing special variable names as special paths
Description
SmartJoin incorrectly treats ordinary relative paths containing special variable names such as .ROOT_DIR as absolute/special paths, causing them to bypass the base-directory join.
What did you do?
I called SmartJoin with a normal relative path whose directory name happens to contain one of the special variable names:
SmartJoin(base, filepath.Join("project.ROOT_DIR", "file.txt"))A minimal regression test demonstrating the issue is:
func TestSmartJoinRelativePathContainingSpecialVariableName(t *testing.T) {
base := filepath.Join("base", "dir")
path := filepath.Join("project.ROOT_DIR", "file.txt")
got := SmartJoin(base, path)
want := filepath.Join(base, path)
if got != want {
t.Fatalf("SmartJoin() = %q, want %q", got, want)
}
}It can be run with:
go test ./internal/filepathext -run TestSmartJoinRelativePathContainingSpecialVariableName -count=1What did you expect to happen?
The path should be treated as a normal relative path and joined with base.
In other words:
SmartJoin(base, filepath.Join("project.ROOT_DIR", "file.txt"))should return the same result as:
filepath.Join(base, "project.ROOT_DIR", "file.txt")What happened instead?
SmartJoin returns the input relative path unchanged instead of joining it with base.
The same behavior also appears to affect relative path components containing:
.ROOT_DIR.TASKFILE_DIR.USER_WORKING_DIR
From looking at the implementation, this may be caused by isSpecialDir using strings.Contains to detect special variables. As a result, an ordinary directory name containing one of these strings can be matched even when the variable is not actually part of a {{ ... }} template expression.
This can cause normal relative paths to bypass the base-directory join and potentially be resolved relative to an unintended location, including paths used for task directories, includes, dotenv files, or fingerprint-related logic.
Version
main (385e5ad92af02877b6d7cf9dcc963b5ed916e70a)
Operating system
Windows amd64, Go 1.26.5
Experiments Enabled
None
Source: go-task/task