Skip to content

Commit dd8dfe0

Browse files
committed
enhance: file scanning with recursion protection and abs path resolution #1178
1 parent 792e871 commit dd8dfe0

File tree

1 file changed

+52
-20
lines changed

1 file changed

+52
-20
lines changed

internal/cache/index.go

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -296,44 +296,76 @@ func (s *Scanner) watchForChanges() {
296296

297297
// scanSingleFile scans a single file and executes all registered callbacks
298298
func (s *Scanner) scanSingleFile(filePath string) error {
299-
// Set scanning state to true
300-
s.scanMutex.Lock()
301-
wasScanning := s.scanning
302-
s.scanning = true
303-
if !wasScanning {
304-
// Only broadcast if status changed from not scanning to scanning
305-
s.statusChan <- true
299+
return s.scanSingleFileWithDepth(filePath, make(map[string]bool), 0)
300+
}
301+
302+
// scanSingleFileWithDepth scans a single file with recursion protection
303+
func (s *Scanner) scanSingleFileWithDepth(filePath string, visited map[string]bool, depth int) error {
304+
// Maximum recursion depth to prevent infinite recursion
305+
const maxDepth = 10
306+
307+
if depth > maxDepth {
308+
logger.Warn("Maximum recursion depth reached for file:", filePath)
309+
return nil
306310
}
307-
s.scanMutex.Unlock()
308311

309-
// Ensure we reset scanning state when done
310-
defer func() {
312+
// Resolve the absolute path to handle symlinks properly
313+
absPath, err := filepath.Abs(filePath)
314+
if err != nil {
315+
logger.Error("Failed to resolve absolute path for:", filePath, err)
316+
return err
317+
}
318+
319+
// Check for circular includes
320+
if visited[absPath] {
321+
// Circular include detected, skip this file
322+
return nil
323+
}
324+
325+
// Mark this file as visited
326+
visited[absPath] = true
327+
328+
// Set scanning state to true only for the root call (depth 0)
329+
var wasScanning bool
330+
if depth == 0 {
311331
s.scanMutex.Lock()
312-
s.scanning = false
313-
// Broadcast the completion
314-
s.statusChan <- false
332+
wasScanning = s.scanning
333+
s.scanning = true
334+
if !wasScanning {
335+
// Only broadcast if status changed from not scanning to scanning
336+
s.statusChan <- true
337+
}
315338
s.scanMutex.Unlock()
316-
}()
339+
340+
// Ensure we reset scanning state when done (only for root call)
341+
defer func() {
342+
s.scanMutex.Lock()
343+
s.scanning = false
344+
// Broadcast the completion
345+
s.statusChan <- false
346+
s.scanMutex.Unlock()
347+
}()
348+
}
317349

318350
// Open the file
319-
file, err := os.Open(filePath)
351+
file, err := os.Open(absPath)
320352
if err != nil {
321353
return err
322354
}
323355
defer file.Close()
324356

325357
// Read the entire file content
326-
content, err := os.ReadFile(filePath)
358+
content, err := os.ReadFile(absPath)
327359
if err != nil {
328360
return err
329361
}
330362

331363
// Execute all registered callbacks
332364
scanCallbacksMutex.RLock()
333365
for _, callback := range scanCallbacks {
334-
err := callback(filePath, content)
366+
err := callback(absPath, content)
335367
if err != nil {
336-
logger.Error("Callback error for file", filePath, ":", err)
368+
logger.Error("Callback error for file", absPath, ":", err)
337369
}
338370
}
339371
scanCallbacksMutex.RUnlock()
@@ -363,7 +395,7 @@ func (s *Scanner) scanSingleFile(filePath string) error {
363395
for _, matchedFile := range matchedFiles {
364396
fileInfo, err := os.Stat(matchedFile)
365397
if err == nil && !fileInfo.IsDir() {
366-
err = s.scanSingleFile(matchedFile)
398+
err = s.scanSingleFileWithDepth(matchedFile, visited, depth+1)
367399
if err != nil {
368400
logger.Error("Failed to scan included file:", matchedFile, err)
369401
}
@@ -379,7 +411,7 @@ func (s *Scanner) scanSingleFile(filePath string) error {
379411

380412
fileInfo, err := os.Stat(includePath)
381413
if err == nil && !fileInfo.IsDir() {
382-
err = s.scanSingleFile(includePath)
414+
err = s.scanSingleFileWithDepth(includePath, visited, depth+1)
383415
if err != nil {
384416
logger.Error("Failed to scan included file:", includePath, err)
385417
}

0 commit comments

Comments
 (0)