Skip to content

Commit c26ca58

Browse files
author
razvan
committed
fix(engine): guard StartIndexingAsync against invalid workspace roots
Export IsInvalidRoot from the watch package and apply it as a safety check at the very start of StartIndexingAsync, before any job registration or SaveIndexStatus call. This prevents accidental indexing of dangerous paths such as the user home directory (~), filesystem root (/), or /tmp — which would cause .ragcode/index_status.json to be written outside any real workspace. - pkg/workspace/watch: isInvalidRoot → IsInvalidRoot (exported + docstring) - internal/service/engine: guard added as first check in StartIndexingAsync
1 parent dd4a532 commit c26ca58

3 files changed

Lines changed: 12 additions & 3 deletions

File tree

cmd/rag-code-mcp/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717
)
1818

1919
var (
20-
Version = "2.1.65"
20+
Version = "2.1.66"
2121
Commit = "none"
2222
Date = "24.10.2025"
2323
)

internal/service/engine/engine.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,11 @@ func (e *Engine) tryStartPendingIndex(root, workspaceID string) {
777777
// If recreate=true and a job is already running, the recreate is queued and
778778
// will start immediately after the current job finishes.
779779
func (e *Engine) StartIndexingAsync(root, id string, changedFiles []string, recreate bool) {
780+
if watch.IsInvalidRoot(root) {
781+
logger.Instance.Error("[IDX] ⛔ Refusing to index invalid/dangerous root: %s", root)
782+
return
783+
}
784+
780785
if _, loaded := e.indexingJobs.LoadOrStore(id, time.Now()); loaded {
781786
// A job is already running. If recreate=true, queue it so it fires
782787
// after the current job finishes (via tryStartPendingIndex/defer).

pkg/workspace/watch/watcher.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func NewFileWatcher(root string, opts Options, onChange func(context.Context, st
8787

8888
// Start begins watching the directory tree.
8989
func (fw *FileWatcher) Start() {
90-
if isInvalidRoot(fw.root) {
90+
if IsInvalidRoot(fw.root) {
9191
logger.Instance.Error("Cannot start watcher on invalid root directory: %s", fw.root)
9292
return
9393
}
@@ -231,7 +231,11 @@ func normalizeExclude(patterns []string) map[string]struct{} {
231231
return result
232232
}
233233

234-
func isInvalidRoot(root string) bool {
234+
// IsInvalidRoot reports whether root is an unsafe or degenerate directory
235+
// that must not be used as a workspace root for indexing or watching.
236+
// It rejects the filesystem root (/), the user home directory (~),
237+
// and the system temp directory.
238+
func IsInvalidRoot(root string) bool {
235239
clean := filepath.Clean(strings.TrimSpace(root))
236240
if clean == "" || clean == "." {
237241
return true

0 commit comments

Comments
 (0)