diff --git a/internal/shared/clients.go b/internal/shared/clients.go index ee51b049..f9ccd86b 100644 --- a/internal/shared/clients.go +++ b/internal/shared/clients.go @@ -222,7 +222,12 @@ func (c *ClientFactory) InitSDKConfig(ctx context.Context, dirPath string) error return slackerror.New(slackerror.ErrHooksJSONLocation) } // Move upward one directory level - dirPath = filepath.Dir(dirPath) + parentDir := filepath.Dir(dirPath) + if parentDir == dirPath { + // Reached a filesystem root not covered above (e.g. D:\ when SYSTEMROOT is on C:\) + return slackerror.New(slackerror.ErrHooksJSONLocation) + } + dirPath = parentDir } configFileBytes, err := afero.ReadFile(c.Fs, hooksJSONFilePath) if err != nil { diff --git a/internal/shared/clients_test.go b/internal/shared/clients_test.go index 77897b1b..c7360213 100644 --- a/internal/shared/clients_test.go +++ b/internal/shared/clients_test.go @@ -110,6 +110,12 @@ func Test_ClientFactory_InitSDKConfig(t *testing.T) { mockWorkingDirectory: filepath.Join("path", "outside", "home", "to", "project"), expectedError: slackerror.New(slackerror.ErrHooksJSONLocation), }, + "errors if traversal reaches a filesystem root": { + mockHooksJSONContent: "{}", + mockHooksJSONFilePath: filepath.Join(string(filepath.Separator), "other", "volume", "project", "package.json"), + mockWorkingDirectory: filepath.Join(string(filepath.Separator), "other", "volume", "project"), + expectedError: slackerror.New(slackerror.ErrHooksJSONLocation), + }, } for name, tc := range tests { t.Run(name, func(t *testing.T) {