# UNDF: UNDF-2026-000000492
# opentofu-0001: filterTfPathsWithTofuAlternatives O(N²) path scan

## Classification
- **Severity**: MEDIUM
- **CWE**: CWE-407 (Algorithmic Complexity — Inefficient Algorithmic Complexity)
- **Component**: `internal/configs/parser_config_dir.go`

## Location
`internal/configs/parser_config_dir.go`, function `filterTfPathsWithTofuAlternatives()`, lines 281–300

```go
for _, p := range paths {
    ext := tfFileExt(p)
    if ext == "" {
        relevantPaths = append(relevantPaths, p)
        continue
    }
    parallelTofuExt := strings.ReplaceAll(ext, ".tf", ".tofu")
    pathWithoutExt, _ := strings.CutSuffix(p, ext)
    parallelTofuPath := pathWithoutExt + parallelTofuExt

    // O(N) scan on every iteration → O(N²) total
    if slices.Contains(paths, parallelTofuPath) {
        ignoredPaths = append(ignoredPaths, p)
    } else {
        relevantPaths = append(relevantPaths, p)
    }
}
```

## Pattern
`slices.Contains(paths, parallelTofuPath)` is called inside `for _, p := range paths`, performing a full O(N) linear scan of all N paths for each of N iterations → O(N²) total.

Called from `loadConfigDir()` for primary, override, and test file sets. In a large Terraform/OpenTofu module directory with N=500 `.tf` files (e.g. generated or auto-split configs), this performs 250,000 string comparisons per directory load.

## Speedup
At N=500 paths: 250,000 comparisons → 500 comparisons (500x reduction)

## Patch

```diff
--- a/internal/configs/parser_config_dir.go
+++ b/internal/configs/parser_config_dir.go
@@ -272,6 +272,11 @@ func filterTfPathsWithTofuAlternatives(paths []string) []string {
 func filterTfPathsWithTofuAlternatives(paths []string) []string {
 	var ignoredPaths []string
 	var relevantPaths []string
+
+	// Pre-build a set for O(1) membership tests instead of O(N) slices.Contains
+	pathSet := make(map[string]bool, len(paths))
+	for _, p := range paths {
+		pathSet[p] = true
+	}

 	for _, p := range paths {
 		ext := tfFileExt(p)
@@ -284,7 +289,7 @@ func filterTfPathsWithTofuAlternatives(paths []string) []string {
 		pathWithoutExt, _ := strings.CutSuffix(p, ext)
 		parallelTofuPath := pathWithoutExt + parallelTofuExt

-		if slices.Contains(paths, parallelTofuPath) {
+		if pathSet[parallelTofuPath] {
 			ignoredPaths = append(ignoredPaths, p)
 		} else {
 			relevantPaths = append(relevantPaths, p)
```

## Complexity
- Before: O(N²) — N = number of files in directory
- After: O(N) — map lookup is O(1) amortized
