# UNDF: UNDF-2026-000000456
# love2d-0003: Filesystem::allowMountingForPath O(n) dedup each call — CWE-407

**Severity:** LOW
**File:** `src/modules/filesystem/physfs/Filesystem.cpp`
**Function:** `Filesystem::allowMountingForPath()`
**Line:** 972

## Description

`allowMountingForPath()` deduplicates an allowlist of mount paths using
`std::find` on a `std::vector<std::string>` before every insert:

```cpp
void Filesystem::allowMountingForPath(const std::string &path)
{
    if (std::find(allowedMountPaths.begin(), allowedMountPaths.end(), path) == allowedMountPaths.end())
        allowedMountPaths.push_back(path);   // O(n) scan every call — CWE-407
}
```

Each call is O(n) where n is the size of `allowedMountPaths`. The same path
is also re-scanned twice in `mount()` (line 387) and `unmount()` (line 513),
once each. With N paths allowed, N mount operations costs O(N²) total.

## Fix

Replace `allowedMountPaths` vector with `std::unordered_set<std::string>`:

```cpp
// FIX love2d-0003: unordered_set replaces O(n) vector scan — CWE-407
// In Filesystem.h, change:
//   std::vector<std::string> allowedMountPaths;
// to:
//   std::unordered_set<std::string> allowedMountPaths;

void Filesystem::allowMountingForPath(const std::string &path)
{
    allowedMountPaths.insert(path);  // O(1) amortized
}

// In mount():
auto it = allowedMountPaths.find(archive);   // O(1) was O(n)

// In unmount():
auto it = allowedMountPaths.find(archive);   // O(1) was O(n)
if (it != allowedMountPaths.end())
    return unmountFullPath(archive);
```

## Patch

```diff
--- a/src/modules/filesystem/physfs/Filesystem.h
+++ b/src/modules/filesystem/physfs/Filesystem.h
@@ -34,6 +34,7 @@
+#include <unordered_set>
 #include <vector>
 #include <string>

-	std::vector<std::string> allowedMountPaths;
+	std::unordered_set<std::string> allowedMountPaths;   // FIX love2d-0003: O(1) lookup — CWE-407

--- a/src/modules/filesystem/physfs/Filesystem.cpp
+++ b/src/modules/filesystem/physfs/Filesystem.cpp
@@ -387,7 +387,7 @@ bool Filesystem::mount(const char *archive, const char *mountpoint, bool append
-	auto it = std::find(allowedMountPaths.begin(), allowedMountPaths.end(), archive);
+	auto it = allowedMountPaths.find(archive);    // O(1) was O(n)

@@ -513,7 +513,7 @@ bool Filesystem::unmount(const char *archive)
-	auto it = std::find(allowedMountPaths.begin(), allowedMountPaths.end(), archive);
+	auto it = allowedMountPaths.find(archive);    // O(1) was O(n)

@@ -970,7 +970,6 @@ void Filesystem::allowMountingForPath(const std::string &path)
-	if (std::find(allowedMountPaths.begin(), allowedMountPaths.end(), path) == allowedMountPaths.end())
-		allowedMountPaths.push_back(path);
+	allowedMountPaths.insert(path);               // O(1) amortized, set semantics
```
